概念
在使用前缀查询(prefix)及通配符查询(wildcard)时,本质上讲都是对多个关键词的查询;在这个概念的基础上,elasticsearch对用户的查询进行了重写(例如将前缀查询优化为should的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"}'
我们要找到name以J开头的文档,即name域中包含以J开头的term:
{
"query": {
"prefix": {
"carNo": {
"value": "J"
}
}
}
}
优化:
{
"query": {
"prefix": {
"carNo": {
"value": "J",
"rewrite": "constant_score_boolean"
}
}
}
}
增加了rewrite查询,lucene会列举倒排索引中存在以J为前缀的关键词,并且每个词都构建出一个query对象,性能会有所提升:
{
"query" : {
"constant_score" : {
"query" : {
"bool" : {
"should" : [
{
"term" : {
"name" : "jack"
}
},
{
"term" : {
"name" : "jane"
}
},
{
"term" : {
"name" : "joe"
}
}
]
}
}
}
}
}
查询重写的相关属性:
scoring_boolean:该重写方法将对应的关键词转换成布尔查询的布尔Should子句,它有可能是CPU密集型的(因为每个关键词都需要计算得分),而且如果关键词数量太多,则会超出布尔查询的限制,限制条件的上限是1024。与此同时,该类型的查询语句还保存计算的得分。布尔查询的默认数量限制可以通过修改elasticsearch.yml文件中的index.query.bool.max_clause_count属性值来修改。但始终要记住的是,产生的布尔查询子句越多,查询的性能越低。
constant_score_boolean:该重写方法与上面提到的scoring_boolean重写方法类似,但是CPU消耗要低很多,因为它不计算得分,每个关键词的得分就是查询的权重,默认是1,也可以通过权重属性来设置其它的值。与scoring_boolean重写方法类似,该方法也受到布尔查询数量的限制。
constant_score_filter:如Apache Lucene Javadocs中所述,该重写方法通过对前缀创建一个私有的过滤器,然后查询文档。(即把查询处理成过滤模式) 。对于匹配的文档,给定一个与查询权重一样的得分。该方法比scoring_boolean要快,特别是索引中匹配的文档或者与前缀匹配的关键词数量比较大时。
top_terms_N:该重写方法将对应的关键词转换成布尔查询的布尔Should子句,同时保存计算得分。只是与scoring_boolean不同点在于,它只保留前N个关键词,来避免触发布尔子句数量的上限。
top_terms_boost_N:该重写方法与top_terms_N类似,只是得分的计算只与权重有关,与查询词无关。