bfe39e45a9
5. 修改统一认证登录和管理员登录是通过接口形式进行,存储返回的accessToken。 6. 修改交叉评查的部分样式
7.3 KiB
7.3 KiB
PostgREST查询参考
过滤运算符完整列表
比较运算符
| 运算符 | 说明 | PostgREST语法 | JavaScript示例 |
|---|---|---|---|
| eq | 等于 | field=eq.value |
{ field: 'eq.value' } |
| neq | 不等于 | field=neq.value |
{ field: 'neq.value' } |
| gt | 大于 | field=gt.value |
{ field: 'gt.100' } |
| gte | 大于等于 | field=gte.value |
{ field: 'gte.100' } |
| lt | 小于 | field=lt.value |
{ field: 'lt.100' } |
| lte | 小于等于 | field=lte.value |
{ field: 'lte.100' } |
模式匹配运算符
| 运算符 | 说明 | PostgREST语法 | JavaScript示例 |
|---|---|---|---|
| like | 模糊匹配(区分大小写) | field=like.*pattern* |
{ field: 'like.*测试*' } |
| ilike | 模糊匹配(不区分大小写) | field=ilike.*pattern* |
{ field: 'ilike.*TEST*' } |
模式匹配通配符:
*: 匹配任意字符(等同于SQL的%)_: 匹配单个字符
示例:
// 查询标题以"合同"开头的文档
{ title: 'like.合同*' }
// 查询标题以"合同"结尾的文档
{ title: 'like.*合同' }
// 查询标题包含"合同"的文档
{ title: 'like.*合同*' }
// 不区分大小写查找
{ title: 'ilike.*contract*' }
列表运算符
| 运算符 | 说明 | PostgREST语法 | JavaScript示例 |
|---|---|---|---|
| in | 在列表中 | field=in.(value1,value2,...) |
{ field: 'in.(active,pending)' } |
| cs | 包含(数组字段) | field=cs.{value1,value2} |
{ tags: 'cs.{重要,紧急}' } |
| cd | 被包含(数组字段) | field=cd.{value1,value2} |
{ tags: 'cd.{重要,紧急}' } |
| ov | 重叠(数组字段) | field=ov.{value1,value2} |
{ tags: 'ov.{重要,紧急}' } |
示例:
// 查询状态为active或pending的文档
{ status: 'in.(active,pending)' }
// 查询ID在[1, 2, 3]中的文档
{ id: 'in.(1,2,3)' }
// 查询标签包含"重要"和"紧急"的文档(数组字段)
{ tags: 'cs.{重要,紧急}' }
Null检查运算符
| 运算符 | 说明 | PostgREST语法 | JavaScript示例 |
|---|---|---|---|
| is | 是null | field=is.null |
{ field: 'is.null' } |
| nt | 不是null | field=nt.null (或 is.not.null) |
{ field: 'nt.null' } |
示例:
// 查询deleted_at为null的文档(未删除)
{ deleted_at: 'is.null' }
// 查询deleted_at不为null的文档(已删除)
{ deleted_at: 'nt.null' }
排序
单字段排序
// 按创建时间升序
{ order: 'created_at.asc' }
// 按创建时间降序
{ order: 'created_at.desc' }
多字段排序
// 先按状态升序,再按创建时间降序
{ order: 'status.asc,created_at.desc' }
分页
Limit和Offset
// 每页10条,第1页
{ limit: 10, offset: 0 }
// 每页10条,第2页
{ limit: 10, offset: 10 }
// 每页20条,第3页
{ limit: 20, offset: 40 }
获取总数
PostgREST会在响应头中返回Content-Range,包含总记录数:
Content-Range: 0-9/50
表示:返回第0-9条记录,总共50条记录。
解析示例:
const response = await apiClient.get('/postgrest/documents', {
params: { limit: 10, offset: 0 }
});
const contentRange = response.headers['content-range'];
const total = parseInt(contentRange.split('/')[1]); // 50
字段选择
选择特定字段
// 只返回id, title, status字段
{ select: 'id,title,status' }
嵌套查询(外键关联)
PostgREST支持嵌套查询,但DocAuditAI暂未启用此功能。
高级查询
逻辑运算符
注意: 前端应避免使用or、and、not参数,这些参数由后端自动生成(用于数据范围和交叉评查权限)。
复杂查询示例
// 查询状态为active且创建时间在2025年之后的文档,按创建时间降序,每页10条
const params = {
status: 'eq.active',
created_at: 'gte.2025-01-01',
order: 'created_at.desc',
limit: 10,
offset: 0
};
const response = await apiClient.get('/postgrest/documents', { params });
完整示例
示例1:文档列表查询
// 需求:查询标题包含"合同"、状态为active的文档,
// 按创建时间降序排列,每页20条,第2页
async function getDocumentList() {
const response = await apiClient.get('/postgrest/documents', {
params: {
title: 'ilike.*合同*',
status: 'eq.active',
order: 'created_at.desc',
limit: 20,
offset: 20 // 第2页
}
});
return {
data: response.data,
total: parseInt(response.headers['content-range'].split('/')[1])
};
}
示例2:高级搜索
// 需求:搜索2025年创建的、状态为active或pending的文档
async function advancedSearch() {
const response = await apiClient.get('/postgrest/documents', {
params: {
status: 'in.(active,pending)',
created_at: 'gte.2025-01-01',
created_at: 'lt.2026-01-01', // 注意:PostgREST会组合多个同名参数
order: 'created_at.desc'
}
});
return response.data;
}
示例3:分页封装
// 通用分页函数
async function fetchPaginated(table, page, pageSize, filters = {}) {
const params = {
limit: pageSize,
offset: (page - 1) * pageSize,
...filters
};
const response = await apiClient.get(`/postgrest/${table}`, { params });
const contentRange = response.headers['content-range'];
const total = contentRange ? parseInt(contentRange.split('/')[1]) : 0;
return {
data: response.data,
total: total,
page: page,
pageSize: pageSize,
totalPages: Math.ceil(total / pageSize)
};
}
// 使用示例
const result = await fetchPaginated('documents', 1, 10, {
status: 'eq.active',
order: 'created_at.desc'
});
console.log(`共${result.total}条记录,第${result.page}/${result.totalPages}页`);
性能优化建议
1. 始终使用分页
// ✅ 好的做法
{ limit: 10, offset: 0 }
// ❌ 不好的做法(返回所有数据)
{}
2. 只查询需要的字段
// ✅ 好的做法(只查询id和title)
{ select: 'id,title' }
// ❌ 不好的做法(查询所有字段)
{}
3. 使用索引字段进行过滤
优先使用已建立索引的字段(如id, user_id, ou_id, status)进行过滤,提升查询性能。
4. 避免过度模糊查询
// ✅ 好的做法(明确的过滤条件)
{ title: 'like.合同*' }
// ❌ 不好的做法(前后通配符,性能差)
{ title: 'like.*合同*' }
常见错误
错误1:运算符拼写错误
// ❌ 错误
{ status: 'equal.active' } // 应该是 eq
// ✅ 正确
{ status: 'eq.active' }
错误2:日期格式错误
// ❌ 错误
{ created_at: 'gte.2025/01/01' } // 格式错误
// ✅ 正确
{ created_at: 'gte.2025-01-01' } // ISO 8601格式
错误3:in运算符语法错误
// ❌ 错误
{ status: 'in.active,pending' } // 缺少括号
// ✅ 正确
{ status: 'in.(active,pending)' }