验证查询语句是否有效,检查查询语法和参数,不实际执行查询。
API #
GET /_validate/query
POST /_validate/query
GET /{index}/_validate/query
POST /{index}/_validate/query
API 的作用 #
该 API 用于验证查询语句的有效性,帮助调试和优化查询。
验证 API 的功能 #
| 功能 | 描述 |
|---|---|
| 语法检查 | 验证查询语法是否正确 |
| 错误信息 | 提供详细的错误信息 |
| 重写查询 | 显示实际执行的 Lucene 查询 |
| 验证范围 | 在索引或分片级别验证 |
与 Explain API 的区别 #
| API | 用途 |
|---|---|
/_validate/query | 验证查询语法,不检查具体文档 |
/_explain/{id} | 计算特定文档的评分 |
API 的参数 #
路由参数 #
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
{index} | 字符串 | 否 | 索引名称。支持:单个索引、逗号分隔的多个索引、通配符表达式 |
Query String 参数 #
验证控制参数 #
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
explain | 布尔值 | 否 | false | 是否返回详细的错误信息 |
rewrite | 布尔值 | 否 | false | 是否提供实际的 Lucene 查询语句 |
all_shards | 布尔值 | 否 | false | 是否在所有分片上执行验证 |
查询参数 #
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
q | 字符串 | 否 | - | Lucene 查询字符串 |
analyzer | 字符串 | 否 | - | 查询字符串的分析器 |
analyze_wildcard | 布尔值 | 否 | false | 是否分析通配符和前缀查询 |
default_operator | 枚举值 | 否 | OR | 默认操作符:AND、OR |
df | 字符串 | 否 | - | 查询字符串的默认字段 |
lenient | 布尔值 | 否 | false | 是否忽略基于格式的失败 |
索引选项参数 #
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
ignore_unavailable | 布尔值 | 否 | false | 是否忽略不可用的索引 |
allow_no_indices | 布尔值 | 否 | false | 是否允许空索引结果 |
expand_wildcards | 枚举值 | 否 | open | 通配符展开方式 |
请求体参数(POST) #
{
"query": { ... }
}
示例 #
验证查询语法 #
POST /my_index/_validate/query
{
"query": {
"bool": {
"must": [
{ "match": { "title": "search" } }
],
"filter": [
{ "term": { "status": "published" } }
]
}
}
}
有效响应:
{
"valid": true,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
}
}
验证无效查询 #
POST /my_index/_validate/query
{
"query": {
"match": {
"title": 123
}
}
}
无效响应:
{
"valid": false,
"error": "org.easysearch.index.query.QueryShardException: [match] failed to parse query"
}
获取详细错误信息 #
POST /my_index/_validate/query?explain=true
{
"query": {
"match": { "message": "search" }
}
}
重写查询 #
POST /my_index/_validate/query?rewrite=true
{
"query": {
"query_string": {
"query": "title:search OR content:search"
}
}
}
响应示例:
{
"valid": true,
"shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"explanations": [
{
"index": "my_index",
"shard": 0,
"node": "node1",
"explanation": "..."
}
]
}
在所有分片上验证 #
POST /my_index/_validate/query?all_shards=true
{
"query": {
"term": { "user": "kimchy" }
}
}
使用查询字符串 #
GET /my_index/_validate/query?q=title:easysearch
带查询字符串参数 #
GET /my_index/_validate/query?q=title:search&lenient=true
验证多索引查询 #
POST /index1,index2/_validate/query
{
"query": {
"match_all": {}
}
}
使用通配符 #
POST /logs-*/_validate/query
{
"query": {
"range": {
"@timestamp": {
"gte": "now-1d"
}
}
}
}
响应字段说明 #
有效查询响应 #
| 字段 | 描述 |
|---|---|
valid | 是否有效(true) |
_shards | 分片信息 |
explanations | 重写查询的解释(rewrite=true 时) |
无效查询响应 #
| 字段 | 描述 |
|---|---|
valid | 是否有效(false) |
error | 错误信息 |
explanations | 分片级别的验证详情 |
使用场景 #
场景 1:查询开发 #
POST /my_index/_validate/query?explain=true
{
"query": {
"bool": {
"must": [
{ "match": { "title": "search" } },
{ "range": { "created_at": { "gte": "2026-01-01" } } }
]
}
}
}
场景 2:语法调试 #
POST /my_index/_validate/query
{
"query": {
"query_string": {
"query": "title:(easysearch) AND status:active"
}
}
}
场景 3:性能优化 #
POST /my_index/_validate/query?rewrite=true
{
"query": {
"bool": {
"should": [
{ "match": { "title": "test" } },
{ "match": { "content": "test" } }
]
}
}
}
场景 4:复杂查询验证 #
POST /my_index/_validate/query
{
"query": {
"nested": {
"path": "comments",
"query": {
"match": {
"comments.author": "john"
}
}
}
}
}
常见错误 #
语法错误 #
{
"valid": false,
"error": "org.easysearch.common.parsing ParsingException: [match] malformed query, ..."
}
字段不存在 #
{
"valid": false,
"error": "No mapping found for [nonexistent_field] in order to sort on"
}
类型不匹配 #
{
"valid": false,
"error": "Cannot use range query on [price] of type [text]"
}
最佳实践 #
- 开发阶段:在开发阶段使用验证 API 检查查询
- 复杂查询:验证复杂的 Bool 和 Nested 查询
- 重构查询:使用 rewrite 查看优化后的查询
- 多索引:在跨索引查询前验证
- 生产部署:部署前验证查询的正确性
注意事项 #
- 不返回数据:只验证查询,不返回文档
- 性能开销:explain=true 会增加性能开销
- 分片验证:all_shards=true 会增加开销
- 类型已弃用:有类型的 API 已被弃用





