查询可以变得非常的复杂,尤其和不同的分析器与不同的字段映射结合时,理解起来就有点困哪了。不过validate-query API可以用来验证查询是否合法。

  1. GET /gb/tweet/_validate/query
  2. {
  3. "query": {
  4. "tweet" : {
  5. "match" : "really powerful"
  6. }
  7. }
  8. }

以上validate 请求的应答告诉我们这个查询时不合法的:

  1. {
  2. "valid" : false,
  3. "_shards" : {
  4. "total" : 1,
  5. "successful" : 1,
  6. "failed" : 0
  7. }
  8. }

理解错误信息

为了找出查询不合法的原因,可以将explain 参数加到查询字符串中:

  1. GET /gb/tweet/_validate/query?explain //1
  2. {
  3. "query": {
  4. "tweet" : {
  5. "match" : "really powerful"
  6. }
  7. }
  8. }
  1. explain 参数可以提供更多关于查询不合法的信息。

很明显,我们将查询类型(match)与字段名称(tweet)搞混了:

  1. {
  2. "valid" : false,
  3. "_shards" : { ... },
  4. "explanations" : [ {
  5. "index" : "gb",
  6. "valid" : false,
  7. "error" : "org.elasticsearch.index.query.QueryParsingException:
  8. [gb] No query registered for [tweet]"
  9. } ]
  10. }

理解查询语句

对于合法查询,使用explain 参数将返回可读的描述,这对准确理解Elasticsearch 是如何解析你的query 是非常有用的:

  1. GET /_validate/query?explain
  2. {
  3. "query": {
  4. "match" : {
  5. "tweet" : "really powerful"
  6. }
  7. }
  8. }

我们查询的每一个index 都会返回对应的explation,因为每一个index 都有自己的映射和分析器:

  1. {
  2. "valid" : true,
  3. "_shards" : { ... },
  4. "explanations" : [ {
  5. "index" : "us",
  6. "valid" : true,
  7. "explanation" : "tweet:really tweet:powerful"
  8. }, {
  9. "index" : "gb",
  10. "valid" : true,
  11. "explanation" : "tweet:realli tweet:power"
  12. } ]
  13. }

从explanation 中可以看出,匹配really powerful的match 查询被重写为两个针对tweet 字段的single-term查询,一个single-term 查询对应查询字符串分出的一个term。

当然,对于索引us,这两个term 分别是really 和powerful,而对于索引gb,term则分别是realli和power。之所以出现这个情况,是由于我们将索引gb 中tweet 字段的分析器修改为english 分析器。