建议器示例
Elastic Stack
建议功能使用建议器,根据提供的文本推荐相似的词条。建议请求部分在 _search
请求中与查询部分一起定义。如果省略查询部分,则仅返回建议。
有关最新详细信息,请参阅搜索 API。
每个请求可以指定多个建议。每个建议都由一个任意名称标识。在下面的示例中,请求了两个建议。my-suggest-1
和 my-suggest-2
建议都使用 term
建议器,但具有不同的 text
。
POST _search
{
"suggest": {
"my-suggest-1" : {
"text" : "tring out Elasticsearch",
"term" : {
"field" : "message"
}
},
"my-suggest-2" : {
"text" : "kmichy",
"term" : {
"field" : "user.id"
}
}
}
}
以下建议响应示例包含 my-suggest-1
和 my-suggest-2
的建议响应。每个建议部分都包含条目。每个条目实际上是建议文本中的一个令牌,包含建议条目文本、建议文本中原始的起始偏移量和长度,如果找到,则包含任意数量的选项。
{
"_shards": ...
"hits": ...
"took": 2,
"timed_out": false,
"suggest": {
"my-suggest-1": [ {
"text": "tring",
"offset": 0,
"length": 5,
"options": [ {"text": "trying", "score": 0.8, "freq": 1 } ]
}, {
"text": "out",
"offset": 6,
"length": 3,
"options": []
}, {
"text": "elasticsearch",
"offset": 10,
"length": 13,
"options": []
} ],
"my-suggest-2": ...
}
}
每个 options 数组包含一个 option 对象,该对象包括建议文本、其文档频率以及与建议条目文本相比的得分。得分的含义取决于所使用的建议器。词条建议器的得分基于编辑距离。
为了避免建议文本的重复,可以定义全局文本。在下面的示例中,建议文本定义为全局文本,并应用于 my-suggest-1
和 my-suggest-2
建议。
POST _search
{
"suggest": {
"text" : "tring out Elasticsearch",
"my-suggest-1" : {
"term" : {
"field" : "message"
}
},
"my-suggest-2" : {
"term" : {
"field" : "user"
}
}
}
}
在上面的示例中,建议文本也可以指定为建议特定的选项。建议级别的建议文本会覆盖全局级别的建议文本。
term
建议器基于编辑距离建议词条。提供的建议文本在建议词条之前进行分析。建议的词条会针对每个分析后的建议文本令牌提供。term
建议器不考虑请求中的查询部分。
text
- 建议文本。建议文本是一个必需选项,需要在全局或每个建议中设置。
field
- 用于从其中获取候选建议的字段。这是一个必需选项,需要在全局或每个建议中设置。
analyzer
- 用于分析建议文本的分析器。默认为建议字段的搜索分析器。
size
- 每个建议文本令牌返回的最大修正数量。
sort
-
定义如何按建议文本词条对建议进行排序。两个可能的值:
score
:首先按得分排序,然后按文档频率,最后按词条本身。frequency
:首先按文档频率排序,然后按相似度得分,最后按词条本身。
suggest_mode
-
建议模式控制包含哪些建议或控制为哪些建议文本词条建议建议。可以指定三个可能的值:
missing
:仅为索引中不存在的建议文本词条提供建议(默认)。popular
:仅建议在比原始建议文本词条更多文档中出现的建议。always
:根据建议文本中的词条建议任何匹配的建议。
term
建议器提供了一个非常方便的 API,可以按令牌级别在一定字符串距离内访问词语替代项。API 允许单独访问流中的每个令牌,而建议选择留给 API 调用者。然而,通常需要预先选择的建议以呈现给最终用户。phrase
建议器在 term
建议器之上添加了额外的逻辑,以选择整个修正的短语,而不是基于 ngram-language
模型加权的单个令牌。实际上,此建议器能够根据共现和频率做出更好的关于选择哪些令牌的决策。
通常,phrase
建议器需要事先进行特殊映射才能工作。本页上的 phrase
建议器示例需要以下映射才能工作。reverse
分析器仅用于最后一个示例。
PUT test
{
"settings": {
"index": {
"number_of_shards": 1,
"analysis": {
"analyzer": {
"trigram": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase","shingle"]
},
"reverse": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase","reverse"]
}
},
"filter": {
"shingle": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 3
}
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"trigram": {
"type": "text",
"analyzer": "trigram"
},
"reverse": {
"type": "text",
"analyzer": "reverse"
}
}
}
}
}
}
POST test/_doc?refresh=true
{"title": "noble warriors"}
POST test/_doc?refresh=true
{"title": "nobel prize"}
设置好分析器和映射后,您可以在使用 term
建议器的相同位置使用 phrase
建议器
POST test/_search
{
"suggest": {
"text": "noble prize",
"simple_phrase": {
"phrase": {
"field": "title.trigram",
"size": 1,
"gram_size": 3,
"direct_generator": [ {
"field": "title.trigram",
"suggest_mode": "always"
} ],
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
}
}
响应包含按最可能的拼写校正得分的建议。在此示例中,我们收到了预期的校正“nobel prize”。
{
"_shards": ...
"hits": ...
"timed_out": false,
"took": 3,
"suggest": {
"simple_phrase" : [
{
"text" : "noble prize",
"offset" : 0,
"length" : 11,
"options" : [ {
"text" : "nobel prize",
"highlighted": "<em>nobel</em> prize",
"score" : 0.48614594
}]
}
]
}
}
field
- 用于执行语言模型 n-gram 查找的字段名称,建议器将使用此字段获取统计信息以对校正进行评分。此字段为必填字段。
gram_size
- 设置
field
中 n-grams (shingles) 的最大大小。如果字段不包含 n-grams (shingles),则应省略或设置为1
。请注意,Elasticsearch 会尝试根据指定的field
检测 gram 大小。如果字段使用shingle
过滤器,则在未明确设置gram_size
时,会将其设置为max_shingle_size
。 real_word_error_likelihood
- 即使词条存在于词典中,该词条被拼错的可能性。默认值为
0.95
,意味着 5% 的真实词语拼写错误。 confidence
- 置信度定义了一个应用于输入短语得分的因子,该因子用作其他建议候选者的阈值。只有得分高于阈值的候选者才会包含在结果中。例如,置信度为
1.0
将仅返回得分高于输入短语的建议。如果设置为0.0
,则返回前 N 个候选者。默认值为1.0
。 max_errors
- 为了形成校正,被认为是拼写错误的词条的最大百分比。此方法接受范围
[0..1)
内的浮点值作为实际查询词条的分数,或接受>=1
的数字作为查询词条的绝对数量。默认设置为1.0
,意味着仅返回最多包含一个拼写错误词条的校正。请注意,设置过高可能会对性能产生负面影响。建议使用1
或2
等较低的值;否则,建议调用花费的时间可能会超过查询执行花费的时间。 separator
- 用于分隔 bigram 字段中词条的分隔符。如果未设置,则使用空格字符作为分隔符。
size
- 为每个单独查询词条生成的候选者数量。
3
或5
等低数字通常能产生良好的结果。提高此值可以带来具有更高编辑距离的词条。默认值为5
。 analyzer
- 设置用于分析建议文本的分析器。默认为通过
field
传递的建议字段的搜索分析器。 shard_size
- 设置从每个独立分片检索的最大建议词条数量。在归约阶段,仅根据
size
选项返回前 N 个建议。默认为5
。 text
- 设置用于提供建议的文本/查询。
highlight
- 设置建议高亮。如果未提供,则不返回
highlighted
字段。如果提供,必须包含准确的pre_tag
和post_tag
,它们将包装更改的令牌。如果连续的多个令牌被更改,则整个更改的令牌短语将被包装,而不是每个令牌。 排序规则
- 根据指定的
query
检查每个建议,以修剪索引中不存在匹配文档的建议。建议的整理查询仅在生成建议的本地分片上运行。query
必须指定,并且可以模板化。请参阅搜索模板。当前建议会自动作为{{suggestion}}
变量可用,该变量应在您的查询中使用。您仍然可以指定自己的模板params
——suggestion
值将添加到您指定的变量中。此外,您可以指定一个prune
来控制是否返回所有短语建议;当设置为true
时,建议将有一个额外的选项collate_match
,如果找到短语的匹配文档,则该值为true
,否则为false
。prune
的默认值为false
。
POST test/_search
{
"suggest": {
"text" : "noble prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"direct_generator" : [ {
"field" : "title.trigram",
"suggest_mode" : "always",
"min_word_length" : 1
} ],
"collate": {
"query": {
"source" : {
"match": {
"{{field_name}}" : "{{suggestion}}"
}
}
},
"params": {"field_name" : "title"},
"prune": true
}
}
}
}
}
- 此查询将针对每个建议运行一次。
{{suggestion}}
变量将替换为每个建议的文本。- 在
params
中指定了额外的field_name
变量,并由match
查询使用。 - 所有建议都将返回一个额外的
collate_match
选项,指示生成的短语是否匹配任何文档。
phrase
建议器支持多种平滑模型,以平衡不常见 grams(索引中不存在的 grams (shingles))和常见 grams(索引中至少出现一次)之间的权重。可以通过将 smoothing
参数设置为以下选项之一来选择平滑模型。每个平滑模型都支持可以配置的特定属性。
stupid_backoff
- 一个简单的回退模型,如果高阶计数为
0
,则回退到低阶 n-gram 模型,并通过一个常数因子折减低阶 n-gram 模型。默认的discount
为0.4
。Stupid Backoff 是默认模型。 laplace
- 一种使用加性平滑的平滑模型,其中向所有计数添加一个常数(通常为
1.0
或更小)以平衡权重。默认的alpha
为0.5
。 linear_interpolation
- 一种平滑模型,根据用户提供的权重 (lambdas) 取 unigrams、bigrams 和 trigrams 的加权平均值。Linear Interpolation 没有默认值。所有参数(
trigram_lambda
、bigram_lambda
、unigram_lambda
)都必须提供。
POST test/_search
{
"suggest": {
"text" : "obel prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"smoothing" : {
"laplace" : {
"alpha" : 0.7
}
}
}
}
}
}
phrase
建议器使用候选生成器为给定文本中的每个词条生成可能的词条列表。单个候选生成器类似于针对文本中每个独立词条调用的 term
建议器。然后,生成器的输出与来自其他词条的候选者组合进行评分,以生成建议候选者。
目前仅支持一种类型的候选生成器:direct_generator
。短语建议 API 在 direct_generator
键下接受一个生成器列表;列表中的每个生成器都会针对原始文本中的每个词条被调用。
直接生成器支持的参数包括
field
- 用于从其中获取候选建议的字段。这是一个必需选项,需要在全局或每个建议中设置。
size
- 每个建议文本令牌返回的最大修正数量。
suggest_mode
-
建议模式控制每个分片生成的建议中包含哪些建议。除了
always
之外的所有值都可以视为一种优化,用于在每个分片上生成更少的建议进行测试,并且在组合每个分片生成的建议时不会重新检查。因此,missing
将为不包含它们的词条在分片上生成建议,即使其他分片包含它们也是如此。这些应使用confidence
进行过滤。可以指定三个可能的值:missing
:仅为分片中不存在的词条生成建议。这是默认设置。popular
:仅建议在分片上比原始词条出现在更多文档中的词条。always
:根据建议文本中的词条建议任何匹配的建议。
max_edits
- 候选建议可以拥有的最大编辑距离,才能被视为建议。值只能在 1 到 2 之间。任何其他值都会抛出 bad request 错误。默认为 2。
prefix_length
- 要成为候选建议,必须匹配的最小前缀字符数。默认为 1。增加此数字可提高拼写检查性能。通常拼写错误不会出现在词条的开头。
min_word_length
- 建议文本词条必须具有的最小长度,才能包含在内。默认为 4。
max_inspections
- 用于与
shard_size
相乘的因子,以便在分片级别检查更多候选拼写校正。可以提高准确性,但会牺牲性能。默认为 5。 min_doc_freq
- 建议应出现的最小文档数阈值。可以指定为绝对数字或文档数的相对百分比。这可以通过仅建议高频词条来提高质量。默认为 0f,未启用。如果指定的值大于 1,则不能是小数。此选项使用分片级别的文档频率。
max_term_freq
- 建议文本令牌可以存在的最大文档数阈值,以便包含在内。可以是相对百分比数字(例如 0.4)或表示文档频率的绝对数字。如果指定的值大于 1,则不能指定小数。默认为 0.01f。这可用于排除高频词条(通常拼写正确)进行拼写检查。这也提高了拼写检查性能。此选项使用分片级别的文档频率。
pre_filter
- 应用于传递给此候选生成器的每个令牌的过滤器(分析器)。此过滤器应用于原始令牌,然后生成候选者。
post_filter
- 应用于每个生成的令牌的过滤器(分析器),然后将它们传递给实际的短语评分器。
以下示例显示了一个带有两个生成器的 phrase
建议调用:第一个使用包含普通索引词条的字段,第二个使用一个使用了 reverse
过滤器索引词条的字段(令牌以反向顺序索引)。这用于克服直接生成器需要恒定前缀才能提供高性能建议的限制。pre_filter
和 post_filter
选项接受普通分析器名称。
POST test/_search
{
"suggest": {
"text" : "obel prize",
"simple_phrase" : {
"phrase" : {
"field" : "title.trigram",
"size" : 1,
"direct_generator" : [ {
"field" : "title.trigram",
"suggest_mode" : "always"
}, {
"field" : "title.reverse",
"suggest_mode" : "always",
"pre_filter" : "reverse",
"post_filter" : "reverse"
} ]
}
}
}
}
pre_filter
和 post_filter
也可用于在生成候选者后注入同义词。例如,对于查询 captain usq
,我们可能会为词条 usq
生成候选词条 usa
,它是 america
的同义词。如果短语得分足够高,这使得我们可以向用户呈现 captain america
。
completion
建议器提供自动补全/搜索时键入 (search-as-you-type) 功能。这是一种导航功能,用于在用户键入时引导他们找到相关结果,提高搜索精度。它不用于拼写校正或“您是不是想找”功能,例如 term
或 phrase
建议器。
理想情况下,自动补全功能应与用户键入的速度一样快,以便提供与用户已键入内容相关的即时反馈。因此,completion
建议器针对速度进行了优化。建议器使用支持快速查找的数据结构,但这些数据结构构建成本高昂且存储在内存中。
要使用completion
建议器,请将您要从中生成建议的字段映射为 completion
类型。这将对字段值进行索引,以实现快速补全。
PUT music
{
"mappings": {
"properties": {
"suggest": {
"type": "completion"
}
}
}
}
analyzer
- 要使用的索引分析器,默认为
simple
。 search_analyzer
- 要使用的搜索分析器,默认为
analyzer
的值。 preserve_separators
- 保留分隔符,默认为
true
。如果禁用,如果您搜索foof
,可能会找到以Foo Fighters
开头的字段。 preserve_position_increments
- 启用位置增量,默认为
true
。如果禁用并使用停用词分析器,如果您搜索b
,可能会得到以The Beatles
开头的字段。注意:您也可以通过索引两个输入(Beatles
和The Beatles
)来实现这一点,如果您能够丰富数据,则无需更改简单的分析器。 max_input_length
- 限制单个输入的长度,默认为 50 个 UTF-16 代码点。此限制仅在索引时使用,以减少每个输入字符串的总字符数,从而防止海量输入导致底层数据结构膨胀。大多数用例不会受到默认值的影响,因为前缀补全很少超过少数字符的前缀。
像索引任何其他字段一样索引建议。建议由一个 input
和一个可选的 weight
属性组成。input
是建议查询期望匹配的文本,weight
决定了建议的得分。索引建议如下:
PUT music/_doc/1?refresh
{
"suggest" : {
"input": [ "Nevermind", "Nirvana" ],
"weight" : 34
}
}
支持的参数包括
input
-
要存储的输入,可以是字符串数组或仅一个字符串。此字段为必填字段。
注意此值不能包含以下 UTF-16 控制字符:
\u0000
(null)\u001f
(信息分隔符一)\u001e
(信息分隔符二)
weight
- 一个正整数或包含正整数的字符串,用于定义权重并允许您对建议进行排序。此字段是可选的。
您可以按如下方式为文档索引多个建议:
PUT music/_doc/1?refresh
{
"suggest": [
{
"input": "Nevermind",
"weight": 10
},
{
"input": "Nirvana",
"weight": 3
}
]
}
您可以使用以下简写形式。请注意,在简写形式中,您不能为建议指定权重。
PUT music/_doc/1?refresh
{
"suggest" : [ "Nevermind", "Nirvana" ]
}
建议的工作方式与往常一样,但您必须将建议类型指定为 completion
。建议是准实时的,这意味着新建议可以通过刷新显示出来,并且一旦删除的文档将永远不会显示。此请求:
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest"
}
}
}
}
- 用于搜索建议的前缀
- 建议类型
- 用于搜索建议的字段名称
它返回此响应:
{
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits": ...
"took": 2,
"timed_out": false,
"suggest": {
"song-suggest" : [ {
"text" : "nir",
"offset" : 0,
"length" : 3,
"options" : [ {
"text" : "Nirvana",
"_index": "music",
"_id": "1",
"_score": 1.0,
"_source": {
"suggest": ["Nevermind", "Nirvana"]
}
} ]
} ]
}
}
_source
元数据字段必须启用,这是默认行为,以启用返回带有建议的 _source
。
建议的配置权重作为 _score
返回。text
字段使用您索引的建议的 input
。默认情况下,建议返回完整的文档 _source
。_source
的大小可能会由于磁盘提取和网络传输开销而影响性能。为了节省一些网络开销,使用源过滤从 _source
中过滤掉不必要的字段,以最小化 _source
大小。请注意,_suggest 端点不支持源过滤,但在 _search
端点上使用 suggest 支持:
POST music/_search
{
"_source": "suggest",
"suggest": {
"song-suggest": {
"prefix": "nir",
"completion": {
"field": "suggest",
"size": 5
}
}
}
}
- 过滤源以仅返回
suggest
字段 - 用于搜索建议的字段名称
- 要返回的建议数量
应如下所示:
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"suggest": {
"song-suggest": [ {
"text": "nir",
"offset": 0,
"length": 3,
"options": [ {
"text": "Nirvana",
"_index": "music",
"_id": "1",
"_score": 1.0,
"_source": {
"suggest": [ "Nevermind", "Nirvana" ]
}
} ]
} ]
}
}
基本完成建议器查询支持的参数包括:
field
- 运行查询的字段名称(必填)。
size
- 要返回的建议数量(默认为
5
)。 skip_duplicates
- 是否过滤掉重复建议(默认为
false
)。
完成建议器考虑索引中的所有文档。有关如何查询文档子集的说明,请参阅上下文建议器。
如果完成查询跨越多个分片,则建议器分两阶段执行,其中后一阶段从分片获取相关文档,这意味着与单个分片执行完成请求由于文档提取开销而性能更高。为了获得最佳完成性能,建议将完成数据索引到单个分片索引中。如果由于分片大小导致堆使用率高,仍然建议将索引分解为多个分片,而不是优化完成性能。
查询可以返回来自不同文档的重复建议。可以通过将 skip_duplicates
设置为 true 来修改此行为。设置后,此选项会从结果中过滤掉具有重复建议的文档。
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"skip_duplicates": true
}
}
}
}
设置为 true 时,此选项可能会减慢搜索速度,因为需要访问更多建议才能找到前 N 个。
完成建议器还支持模糊查询——这意味着您可以在搜索中存在拼写错误,仍然能够获得结果。
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"prefix": "nor",
"completion": {
"field": "suggest",
"fuzzy": {
"fuzziness": 2
}
}
}
}
}
与查询 prefix
共享最长前缀的建议得分会更高。
模糊查询可以接受特定的模糊参数。例如:
fuzziness
- 模糊因子,默认为
AUTO
。有关允许的设置,请参阅模糊性。 transpositions
- 如果设置为
true
,则转置计为一次更改而不是两次更改,默认为true
min_length
- 返回模糊建议之前输入的最小长度,默认为
3
prefix_length
- 输入的最小长度,不检查其模糊替代项,默认为
1
unicode_aware
- 如果为
true
,则所有度量(如模糊编辑距离、转置和长度)都以 Unicode 代码点而不是字节为单位进行测量。这比原始字节略慢,因此默认设置为false
。
如果您想坚持使用默认值,但仍使用模糊功能,可以使用 fuzzy: {}
或 fuzzy: true
。
完成建议器还支持正则表达式查询,这意味着您可以使用正则表达式表示前缀:
POST music/_search?pretty
{
"suggest": {
"song-suggest": {
"regex": "n[ever|i]r",
"completion": {
"field": "suggest"
}
}
}
}
正则表达式查询可以接受特定的正则表达式参数。例如:
flags
- 可能的标志包括
ALL
(默认)、ANYSTRING
、COMPLEMENT
、EMPTY
、INTERSECTION
、INTERVAL
或NONE
。有关其含义,请参阅regexp-syntax。 max_determinized_states
- 正则表达式很危险,因为很容易意外地创建一个看似无害的正则表达式,但它需要 Lucene 执行指数级的内部确定性自动机状态(以及相应的 RAM 和 CPU)。Lucene 使用
max_determinized_states
设置(默认为 10000)来防止这种情况。您可以提高此限制以允许执行更复杂的正则表达式。
完成建议器考虑索引中的所有文档,但通常希望按某些条件过滤和/或提升建议。例如,您想按特定艺术家过滤建议歌曲标题,或者您想根据歌曲的流派提升歌曲标题。
要实现建议过滤和/或提升,您可以在配置完成字段时添加上下文映射。您可以为一个完成字段定义多个上下文映射。每个上下文映射都有一个唯一的名称和一个类型。共有两种类型:category
和 geo
。上下文映射在字段映射的 contexts
参数下配置。
索引和查询启用了上下文的完成字段时,必须提供上下文。
补全字段上下文映射的最大允许数量是 10。
以下示例定义了类型,每种类型都有两个用于补全字段的上下文映射
PUT place
{
"mappings": {
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category"
},
{
"name": "location",
"type": "geo",
"precision": 4
}
]
}
}
}
}
PUT place_path_category
{
"mappings": {
"properties": {
"suggest": {
"type": "completion",
"contexts": [
{
"name": "place_type",
"type": "category",
"path": "cat"
},
{
"name": "location",
"type": "geo",
"precision": 4,
"path": "loc"
}
]
},
"loc": {
"type": "geo_point"
}
}
}
}
- 定义一个名为 place_type 的
category
上下文,其中类别必须与建议一起发送。 - 定义一个名为 location 的
geo
上下文,其中位置数据必须与建议一起发送。 - 定义一个名为 place_type 的
category
上下文,其中类别从cat
字段读取。 - 定义一个名为 location 的
geo
上下文,其中位置数据从loc
字段读取。
添加上下文映射会增加补全字段的索引大小。补全索引完全驻留在堆内存中,您可以使用 索引统计信息 监控补全字段的索引大小。
category
上下文允许您在索引时将一个或多个类别与建议关联。在查询时,可以根据其关联的类别过滤和提升建议。
映射设置类似于上面的 place_type
字段。如果定义了 path
,则类别将从文档中的该路径读取,否则必须在建议字段中像这样发送它们
PUT place/_doc/1
{
"suggest": {
"input": [ "timmy's", "starbucks", "dunkin donuts" ],
"contexts": {
"place_type": [ "cafe", "food" ]
}
}
}
- 这些建议将与 cafe 和 food 类别关联。
如果映射包含 path
,则以下索引请求足以添加类别
PUT place_path_category/_doc/1
{
"suggest": ["timmy's", "starbucks", "dunkin donuts"],
"cat": ["cafe", "food"]
}
- 这些建议将与 cafe 和 food 类别关联。
如果上下文映射引用了另一个字段并且类别被显式索引,则建议将使用两组类别进行索引。
可以通过一个或多个类别过滤建议。以下示例按多个类别过滤建议
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [ "cafe", "restaurants" ]
}
}
}
}
}
如果查询中设置了多个类别或类别上下文,它们将作为析取合并。这意味着如果建议包含至少一个提供的上下文值,则匹配。
具有某些类别的建议可以比其他建议获得更高的提升。以下示例按类别过滤建议,并额外提升与某些类别关联的建议
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"place_type": [
{ "context": "cafe" },
{ "context": "restaurants", "boost": 2 }
]
}
}
}
}
}
- 上下文查询过滤与 cafe 和 restaurants 类别关联的建议,并将与 restaurants 关联的建议提升
2
倍
除了接受类别值外,上下文查询还可以由多个类别上下文子句组成。category
上下文子句支持的参数包括
context
- 要过滤/提升的类别值。这是必填项。
boost
- 建议的分数应乘以该因子进行提升,分数是通过将提升因子乘以建议权重计算得出的,默认值为
1
prefix
- 类别值是否应被视为前缀。例如,如果设置为
true
,您可以通过指定类别前缀 *type* 来过滤 *type1*、*type2* 等类别。默认值为false
如果一个建议条目匹配多个上下文,则最终得分计算为任何匹配上下文产生的最高得分。
geo
上下文允许您在索引时将一个或多个地理点或地理哈希与建议关联。在查询时,如果建议在指定地理位置的一定距离内,则可以对其进行过滤和提升。
在内部,地理点以指定的精度编码为地理哈希。
除了 path
设置外,geo
上下文映射还接受诸如以下设置
precision
- 这定义了要索引的地理哈希精度,可以指定为距离值(如
5m
、10km
等),或作为原始地理哈希精度(1
..12
)。默认值为原始地理哈希精度6
。
索引时的 precision
设置定义了查询时可以使用的最大地理哈希精度。
geo
上下文可以与建议一起显式设置,或者通过 path
参数从文档中的地理点字段进行索引,类似于 category
上下文。将多个地理位置上下文与一个建议关联,将为每个地理位置索引该建议。以下示例索引了一个具有两个地理位置上下文的建议
PUT place/_doc/1
{
"suggest": {
"input": "timmy's",
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353
},
{
"lat": 43.6624718,
"lon": -79.3873227
}
]
}
}
}
建议可以根据其与一个或多个地理点的接近程度进行过滤和提升。以下示例过滤了落在地理点编码地理哈希所表示区域内的建议
POST place/_search
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": {
"lat": 43.662,
"lon": -79.380
}
}
}
}
}
}
在查询时指定较低精度的位置时,所有落在该区域内的建议都将被考虑。
如果查询中设置了多个类别或类别上下文,它们将作为析取合并。这意味着如果建议包含至少一个提供的上下文值,则匹配。
落在地理哈希所表示区域内的建议也可以比其他建议获得更高的提升,如下所示
POST place/_search?pretty
{
"suggest": {
"place_suggestion": {
"prefix": "tim",
"completion": {
"field": "suggest",
"size": 10,
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353,
"precision": 2
},
{
"context": {
"lat": 43.6624803,
"lon": -79.3863353
},
"boost": 2
}
]
}
}
}
}
}
- 上下文查询过滤了落在地理哈希表示的地理位置(经纬度 (43.662, -79.380),精度为 2)下的建议,并将落在地理哈希表示的地理位置(经纬度 (43.6624803, -79.3863353),默认精度为 6)下的建议提升
2
倍
如果一个建议条目匹配多个上下文,则最终得分计算为任何匹配上下文产生的最高得分。
除了接受上下文值外,上下文查询还可以由多个上下文子句组成。geo
上下文子句支持的参数包括
context
- 用于过滤或提升建议的地理点对象或地理哈希字符串。这是必填项。
boost
- 建议的分数应乘以该因子进行提升,分数是通过将提升因子乘以建议权重计算得出的,默认值为
1
precision
- 用于编码查询地理点的地理哈希精度。可以指定为距离值(如
5m
、10km
等),或作为原始地理哈希精度(1
..12
)。默认值为索引时的精度级别。 neighbours
- 接受一个精度值数组,表示应考虑哪些精度下的相邻地理哈希。精度值可以是距离值(如
5m
、10km
等)或原始地理哈希精度(1
..12
)。默认为索引时的精度级别生成邻居。
precision 字段不会产生距离匹配。指定 10km
这样的距离值只会产生表示该尺寸区域的地理哈希精度值。该精度将用于将搜索地理点编码为地理哈希瓦片以进行补全匹配。其结果是,即使非常靠近搜索点,但落在该瓦片之外的点也将不匹配。降低精度或增加距离可以降低发生这种情况的风险,但无法完全消除。
有时您需要知道 suggester 的确切类型以便解析其结果。可以使用 typed_keys
参数更改响应中的 suggester 名称,以便其名称以其类型为前缀。
考虑以下包含两个 suggester 的示例:term
和 phrase
POST _search?typed_keys
{
"suggest": {
"text" : "some test mssage",
"my-first-suggester" : {
"term" : {
"field" : "message"
}
},
"my-second-suggester" : {
"phrase" : {
"field" : "message"
}
}
}
}
在响应中,suggester 名称将分别更改为 term#my-first-suggester
和 phrase#my-second-suggester
,反映了每个建议的类型
{
"suggest": {
"term#my-first-suggester": [
{
"text": "some",
"offset": 0,
"length": 4,
"options": []
},
{
"text": "test",
"offset": 5,
"length": 4,
"options": []
},
{
"text": "mssage",
"offset": 10,
"length": 6,
"options": [
{
"text": "message",
"score": 0.8333333,
"freq": 4
}
]
}
],
"phrase#my-second-suggester": [
{
"text": "some test mssage",
"offset": 0,
"length": 16,
"options": [
{
"text": "some test message",
"score": 0.030227963
}
]
}
]
},
...
}
- 名称
my-first-suggester
现在包含term
前缀。 - 名称
my-second-suggester
现在包含phrase
前缀。