查询重写机制

如果你曾经使用过很多不同的查询类型,比如前缀查询和通配符查询,从本质上上,任何的查询都可以视为对多个关键词的查询。可能用户听说过查询重写(query rewrite),ElasticSearch(实际上是Apache Lucene很明显地)对用户的查询进行了重写,这样做是为了保证性能。整个重写过程是把从Lucene角度认为原始的、开销大的查询对象转变成一系列开销小的查询对象的一个过程。

以前缀查询为例

展示查询重写内部运作机制的最好方法是通过一个例子,查看例子中用户输入的原查询语句中的term在内部被什么Term所取代。假定我们的索引中有如下的数据:

curl  -XPUT  'localhost:9200/clients/client/1'  -d
'{
  "id":"1","name":"Joe"
}'
curl  -XPUT  'localhost:9200/clients/client/2'  -d
'{
  "id":"2","name":"Jane"
}'
curl  -XPUT  'localhost:9200/clients/client/3'  -d
'{
  "id":"3","name":"Jack"
}'
curl  -XPUT  'localhost:9200/clients/client/4'  -d
'{
  "id":"4","name":"Rob"
}'
curl  -XPUT  'localhost:9200/clients/client/5'  -d
'{
  "id":"5","name":"Jannet"
}'


源码下载

所有购买了Packt出版的图书的读者都可以用自己的账户从http://www.packtpub.com. 下载源代码文件。如果读者通过其它的途径下载本书,则需要通过http://www.packtpub.com/support 来注册账号,然后网站会把源码通过e-mail发送到你的邮箱。


我们的目的是找到所有以字符 j 开头的文档。这个需求非常简单,在 client索引上运行如下的查询表达式:

curl -XGET 'localhost:9200/clients/_search?pretty' -d '{
"query" : {
"prefix" : {
"name" : "j",
"rewrite" : "constant_score_boolean"
}
}
}'

我们用的是一个简单的前缀查询;前面说过我们的目的是找到符合以下条件的文档:name域中包含以字符 j 开头的Term。我们用rewrite参数来指定重写查询的方法,关于该参数的取值我们稍后讨论。运行前面的查询命令,我们得到的结果如下:

{ ...
"hits" : {
"total" : 4,
"max_score" : 1.0,
"hits" : [ {
"_index" : "clients",
"_type" : "client",
"_id" : "5",
"_score" : 1.0, "_source" : {"id":"5","name":"Jannet"}
}, {
"_index" : "clients",
"_type" : "client",
"_id" : "1",
"_score" : 1.0, "_source" : {"id":"1", "name":"Joe"}
}, {
"_index" : "clients",
"_type" : "client",
"_id" : "2",
"_score" : 1.0, "_source" : {"id":"2", "name":"Jane"}
}, {
"_index" : "clients",
"_type" : "client",
"_id" : "3",
"_score" : 1.0, "_source" : {"id":"3", "name":"Jack"}
} ]
} }