查询时输入即搜索
把邮编的事情先放一边,让我们先看看前缀查询是如何在全文查询中起作用的。用户已经渐渐习惯在输完查询内容之前,就能为他们展现搜索结果,这就是所谓的 即时搜索(instant search) 或 输入即搜索(search-as-you-type) 。不仅用户能在更短的时间内得到搜索结果,我们也能引导用户搜索索引中真实存在的结果。
例如,如果用户输入 johnnie walker bl
,我们希望在它们完成输入搜索条件前就能得到:Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。
生活总是这样,就像猫的花色远不只一种!我们希望能找到一种最简单的实现方式。并不需要对数据做任何准备,在查询时就能对任意的全文字段实现 输入即搜索(search-as-you-type) 的查询。
在 短语匹配中,我们引入了 match_phrase
短语匹配查询,它匹配相对顺序一致的所有指定词语,对于查询时的输入即搜索,可以使用 match_phrase
的一种特殊形式,match_phrase_prefix
查询:
{
"match_phrase_prefix" : {
"brand" : "johnnie walker bl"
}
}
这种查询的行为与 match_phrase
查询一致,不同的是它将查询字符串的最后一个词作为前缀使用,换句话说,可以将之前的例子看成如下这样:
johnnie
- 跟着
walker
- 跟着以
bl
开始的词
如果通过 validate-query
API 运行这个查询查询,explanation 的解释结果为:
"johnnie walker bl*"
与 match_phrase
一样,它也可以接受 slop
参数(参照 slop )让相对词序位置不那么严格:
{
"match_phrase_prefix" : {
"brand" : {
"query": "walker johnnie bl", <1>
"slop": 10
}
}
}
<1> 尽管词语的顺序不正确,查询仍然能匹配,因为我们为它设置了足够高的 slop
值使匹配时的词序有更大的灵活性。
但是只有查询字符串的最后一个词才能当作前缀使用。
在之前的 前缀查询 中,我们警告过使用前缀的风险,即 prefix
查询存在严重的资源消耗问题,短语查询的这种方式也同样如此。前缀 a
可能会匹配成千上万的词,这不仅会消耗很多系统资源,而且结果的用处也不大。
可以通过设置 max_expansions
参数来限制前缀扩展的影响,一个合理的值是可能是 50 :
{
"match_phrase_prefix" : {
"brand" : {
"query": "johnnie walker bl",
"max_expansions": 50
}
}
}
参数 max_expansions
控制着可以与前缀匹配的词的数量,它会先查找第一个与前缀 bl
匹配的词,然后依次查找搜集与之匹配的词(按字母顺序),直到没有更多可匹配的词或当数量超过 max_expansions
时结束。
不要忘记,当用户每多输入一个字符时,这个查询又会执行一遍,所以查询需要快,如果第一个结果集不是用户想要的,他们会继续输入直到能搜出满意的结果为止。