3.9
查询重写
curl -XPOST 'localhost:9200/library/book/1' -d '{"title": "Solr 4
Cookbook"}'
curl -XPOST 'localhost:9200/library/book/2' -d '{"title": "Solr 3.1
Cookbook"}'
curl -XPOST 'localhost:9200/library/book/3' -d '{"title": "Mastering
Elasticsearch"}'
我们需要找到以字母s开头的所有文档。就这么简单,对该library索引执行以下查询:
curl -XGET 'localhost:9200/library/_search?pretty' -d '{ "query" : { "prefix" : { "title" : "s", "rewrite" : "constant_score_boolean" } } }'
这里,使用一个简单的前缀查询。我们说过要找到所有在title字段中含有字母s的文档。 我们还使用了rewrite属性来指定查询重写方法,但先跳过它,因为会在本节的后半部分讨论此 参数的可能值。
可以看到,在响应中,我们有两个文档,它们的标题字段内容以期望的字符开头。
看看Lucene 级别的查询,我们注意到,前缀查询被重写成类似于下面这样的查询: ConstantScore(title:solr) 这是因为solr是唯一以字母s开头的词条。
这就是查询重写的一切:找到相关的词条,把查 询重写为性能更好的查询,而不是执行昂贵的查询。
3.9.2 查询重写的属性
我们已经说过,可以在任何多项词条查询(比如Elasticsearch的前缀查询和通配符查询)中
使用rewrite参数来控制查询如何被改写。把rewrite参数添加到负责实际查询的JSON对象中,
如下所示:
{
"query" : {
"prefix" : {
"title" : "s",
"rewrite" : "constant_score_boolean"
}
}
}
现在,来看看此参数的值有哪些选项。
scoring_boolean:这种重写方法把生成的每个词条翻译成布尔查询中的一个should子
句。此查询重写方法可能是CPU密集型(因为它计算并存储每个词条的得分),如果查询
许多词条,可能超过布尔查询极限,也就是1024。此外,此查询会存储计算所得的分数。
constant_score_boolean:这种重写方法类似于上面描述的scoring_boolean重写
方法,但是对CPU要求较低,因为不需要计算得分。相反,每个词条都得到一个与查询
加权相等的得分,默认是1,可以通过加权属性进行设置。与scoring_boolean重写方
法类似,该方法也可能达到布尔查询的最高限制。
constant_score_filter:就像Apache Lucene的Javadocs声明的那样,这个重写方法按
顺序访问每个词条,标记该词条的所有文档,并创建一个私有过滤器来重写查询。匹配
的文档都被赋予一个与查询加权相等的常量得分。当匹配词条或文档的数量很大时,此
方法比scoring_boolean和constant_score_boolean快。
top_terms_N:这种重写方法把生成的每个词条翻译成布尔查询中的一个should子句,
并保持查询计算所得的分数。然而,与scoring_boolean重写方法不同,它只会保留N
个最高得分的词条,以免达到布尔查询的最大限制。
top_terms_boost_N:这是一种类似top_terms_N的重写方法。然而,与top_terms_N
重写方法不同,分数只由加权计算而来,而非查询。
当重写属性设置为constant_score_auto或根本没有设置时,根据查询以及
构造方式的不同,将选择使用constant_score_filter或constant_score_
boolean。
结束本章查询重写部分之前,我们应该问自己最后一个问题,“什么时候使用哪种类型的重
写”?这个问题的答案在很大程度上取决于我们的用例,但是总结来说,如果能忍受低精度(但
性能更好),使用top N重写方法。如果需要高精度(但性能较低),选择布尔方法。