20_Match_phrase_prefix.asciidoc 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. [[_query_time_search_as_you_type]]
  2. === 查询时输入即搜索
  3. 把邮编的事情先放一边,让我们先看看前缀查询是如何在全文查询中起作用的。((("partial matching", "query time search-as-you-type")))用户已经渐渐习惯在输完查询内容之前,就能为他们展现搜索结果,这就是所谓的 _即时搜索(instant search)_ 或 _输入即搜索(search-as-you-type)_ 。((("search-as-you-type")))((("instant search")))不仅用户能在更短的时间内得到搜索结果,我们也能引导用户搜索索引中真实存在的结果。
  4. 例如,如果用户输入 `johnnie walker bl` ,我们希望在它们完成输入搜索条件前就能得到:Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。
  5. 生活总是这样,就像猫的花色远不只一种!我们希望能找到一种最简单的实现方式。并不需要对数据做任何准备,在查询时就能对任意的全文字段实现 _输入即搜索(search-as-you-type)_ 的查询。
  6. 在 <<phrase-matching,短语匹配>> 中,我们引入了 `match_phrase` 短语匹配查询,它匹配相对顺序一致的所有指定词语,对于查询时的输入即搜索,可以使用 `match_phrase` 的一种特殊形式,((("prefix query", "match_phrase_prefix query")))((("match_phrase_prefix query"))) `match_phrase_prefix` 查询:
  7. [source,js]
  8. --------------------------------------------------
  9. {
  10. "match_phrase_prefix" : {
  11. "brand" : "johnnie walker bl"
  12. }
  13. }
  14. --------------------------------------------------
  15. // SENSE: 130_Partial_Matching/20_Match_phrase_prefix.json
  16. 这种查询的行为与 `match_phrase` 查询一致,不同的是它将查询字符串的最后一个词作为前缀使用,换句话说,可以将之前的例子看成如下这样:
  17. * `johnnie`
  18. * 跟着 `walker`
  19. * 跟着以 `bl` 开始的词
  20. 如果通过 `validate-query` API 运行这个查询查询,explanation 的解释结果为:
  21. "johnnie walker bl*"
  22. 与 `match_phrase` 一样,它也可以接受 `slop` 参数(参照 <<slop,slop>> )让相对词序位置不那么严格:((("slop parameter", "match_prhase_prefix query")))((("match_phrase_prefix query", "slop parameter")))
  23. [source,js]
  24. --------------------------------------------------
  25. {
  26. "match_phrase_prefix" : {
  27. "brand" : {
  28. "query": "walker johnnie bl", <1>
  29. "slop": 10
  30. }
  31. }
  32. }
  33. --------------------------------------------------
  34. // SENSE: 130_Partial_Matching/20_Match_phrase_prefix.json
  35. <1> 尽管词语的顺序不正确,查询仍然能匹配,因为我们为它设置了足够高的 `slop` 值使匹配时的词序有更大的灵活性。
  36. 但是只有查询字符串的最后一个词才能当作前缀使用。
  37. 在之前的 <<prefix-query,前缀查询>> 中,我们警告过使用前缀的风险,即 `prefix` 查询存在严重的资源消耗问题,短语查询的这种方式也同样如此。((("match_phrase_prefix query", "caution with")))前缀 `a` 可能会匹配成千上万的词,这不仅会消耗很多系统资源,而且结果的用处也不大。
  38. 可以通过设置 `max_expansions` 参数来限制前缀扩展的影响,((("match_phrase_prefix query", "max_expansions")))((("max_expansions parameter")))一个合理的值是可能是 50 :
  39. [source,js]
  40. --------------------------------------------------
  41. {
  42. "match_phrase_prefix" : {
  43. "brand" : {
  44. "query": "johnnie walker bl",
  45. "max_expansions": 50
  46. }
  47. }
  48. }
  49. --------------------------------------------------
  50. // SENSE: 130_Partial_Matching/20_Match_phrase_prefix.json
  51. 参数 `max_expansions` 控制着可以与前缀匹配的词的数量,它会先查找第一个与前缀 `bl` 匹配的词,然后依次查找搜集与之匹配的词(按字母顺序),直到没有更多可匹配的词或当数量超过 `max_expansions` 时结束。
  52. 不要忘记,当用户每多输入一个字符时,这个查询又会执行一遍,所以查询需要快,如果第一个结果集不是用户想要的,他们会继续输入直到能搜出满意的结果为止。