建议器编辑

使用建议器根据提供的文本建议类似的术语。

resp = client.search(
    index="my-index-000001",
    body={
        "query": {"match": {"message": "tring out Elasticsearch"}},
        "suggest": {
            "my-suggestion": {
                "text": "tring out Elasticsearch",
                "term": {"field": "message"},
            }
        },
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match: {
        message: 'tring out Elasticsearch'
      }
    },
    suggest: {
      "my-suggestion": {
        text: 'tring out Elasticsearch',
        term: {
          field: 'message'
        }
      }
    }
  }
)
puts response
POST my-index-000001/_search
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : {
    "my-suggestion" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    }
  }
}

请求编辑

建议功能使用建议器根据提供的文本建议类似的术语。建议请求部分与查询部分一起定义在 _search 请求中。如果省略查询部分,则只返回建议。

示例编辑

每个请求可以指定多个建议。每个建议都用一个任意名称标识。在下面的示例中,请求了两个建议。 my-suggest-1my-suggest-2 两个建议都使用 term 建议器,但 text 不同。

resp = client.search(
    body={
        "suggest": {
            "my-suggest-1": {
                "text": "tring out Elasticsearch",
                "term": {"field": "message"},
            },
            "my-suggest-2": {
                "text": "kmichy",
                "term": {"field": "user.id"},
            },
        }
    },
)
print(resp)
response = client.search(
  body: {
    suggest: {
      "my-suggest-1": {
        text: 'tring out Elasticsearch',
        term: {
          field: 'message'
        }
      },
      "my-suggest-2": {
        text: 'kmichy',
        term: {
          field: 'user.id'
        }
      }
    }
  }
)
puts response
POST _search
{
  "suggest": {
    "my-suggest-1" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    },
    "my-suggest-2" : {
      "text" : "kmichy",
      "term" : {
        "field" : "user.id"
      }
    }
  }
}

下面的建议响应示例包含 my-suggest-1my-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": ...
  }
}

每个选项数组都包含一个选项对象,其中包含建议的文本、其文档频率以及与建议条目文本相比的得分。得分的含义取决于使用的建议器。术语建议器的得分基于编辑距离。

全局建议文本编辑

为了避免建议文本的重复,可以定义一个全局文本。在下面的示例中,建议文本在全局定义,并应用于 my-suggest-1my-suggest-2 建议。

$params = [
    'body' => [
        'suggest' => [
            'text' => 'tring out Elasticsearch',
            'my-suggest-1' => [
                'term' => [
                    'field' => 'message',
                ],
            ],
            'my-suggest-2' => [
                'term' => [
                    'field' => 'user',
                ],
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    body={
        "suggest": {
            "text": "tring out Elasticsearch",
            "my-suggest-1": {"term": {"field": "message"}},
            "my-suggest-2": {"term": {"field": "user"}},
        }
    },
)
print(resp)
response = client.search(
  body: {
    suggest: {
      text: 'tring out Elasticsearch',
      "my-suggest-1": {
        term: {
          field: 'message'
        }
      },
      "my-suggest-2": {
        term: {
          field: 'user'
        }
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "suggest": {
	    "text": "tring out Elasticsearch",
	    "my-suggest-1": {
	      "term": {
	        "field": "message"
	      }
	    },
	    "my-suggest-2": {
	      "term": {
	        "field": "user"
	      }
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  body: {
    suggest: {
      text: 'tring out Elasticsearch',
      'my-suggest-1': {
        term: {
          field: 'message'
        }
      },
      'my-suggest-2': {
        term: {
          field: 'user'
        }
      }
    }
  }
})
console.log(response)
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:根据建议文本中的术语建议任何匹配的建议。

其他术语建议选项:编辑

max_edits

候选建议为了被视为建议可以具有的最大编辑距离。只能是 1 到 2 之间的值。任何其他值都会导致抛出错误请求错误。默认为 2。

prefix_length

为了成为建议的候选者,必须匹配的最小前缀字符数。默认为 1。增加此数字可以提高拼写检查性能。通常,拼写错误不会出现在术语的开头。

min_word_length

建议文本术语为了被包含在内必须具有的最小长度。默认为 4

shard_size

设置从每个单独分片检索的最大建议数量。在减少阶段,只返回基于 size 选项的前 N 个建议。默认为 size 选项。将其设置为高于 size 的值可能有助于获得更准确的拼写更正的文档频率,但会以性能为代价。由于术语在分片之间进行分区,因此拼写更正的分片级文档频率可能不精确。增加此值将使这些文档频率更加精确。

max_inspections

一个用于乘以 shard_size 的因子,以便在分片级别检查更多候选拼写更正。可以提高准确性,但会以性能为代价。默认为 5。

min_doc_freq

建议应该出现的文档数量的最小阈值。可以指定为绝对数字或文档数量的相对百分比。这可以通过只建议高频术语来提高质量。默认为 0f 且未启用。如果指定的值高于 1,则该数字不能是分数。分片级文档频率用于此选项。

max_term_freq

建议文本标记为了被包含在内可以存在的文档数量的最大阈值。可以是相对百分比数字(例如,0.4)或表示文档频率的绝对数字。如果指定的值高于 1,则不能指定分数。默认为 0.01f。这可以用来排除高频术语(通常拼写正确)被拼写检查。这也提高了拼写检查性能。分片级文档频率用于此选项。

string_distance

用于比较建议术语的相似程度的字符串距离实现。可以指定五个可能的值

  • internal:基于 damerau_levenshtein 的默认值,但针对比较索引内术语的字符串距离进行了高度优化。
  • damerau_levenshtein:基于 Damerau-Levenshtein 算法的字符串距离算法。
  • levenshtein:基于 Levenshtein 编辑距离算法的字符串距离算法。
  • jaro_winkler:基于 Jaro-Winkler 算法的字符串距离算法。
  • ngram:基于字符 n 元组的字符串距离算法。

短语建议器编辑

term 建议器提供了一个非常方便的 API,用于在特定字符串距离内按标记访问单词替代方案。该 API 允许在流中单独访问每个标记,而建议选择则留给 API 消费者。然而,通常需要预先选择的建议才能呈现给最终用户。 phrase 建议器在 term 建议器之上添加了额外的逻辑,以选择基于 ngram-language 模型加权的整个更正短语,而不是单个标记。在实践中,此建议器将能够根据共现和频率更好地决定选择哪些标记。

API 示例编辑

一般来说, phrase 建议器需要预先进行特殊的映射才能工作。此页面上的 phrase 建议器示例需要以下映射才能工作。 reverse 分析器仅在最后一个示例中使用。

response = client.indices.create(
  index: 'test',
  body: {
    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'
            }
          }
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'test',
  refresh: true,
  body: {
    title: 'noble warriors'
  }
)
puts response

response = client.index(
  index: 'test',
  refresh: true,
  body: {
    title: 'nobel prize'
  }
)
puts response
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
        }]
      }
    ]
  }
}

基本短语建议 API 参数编辑

field

用于对语言模型进行 n 元组查找的字段的名称,建议器将使用此字段来获取统计信息以对更正进行评分。此字段是必需的。

gram_size

设置 field 中 n 元组(分片)的最大大小。如果字段不包含 n 元组(分片),则应省略此选项或将其设置为 1。请注意,Elasticsearch 尝试根据指定的 field 检测元组大小。如果字段使用 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,这意味着只返回最多包含一个拼写错误的词语的更正。请注意,设置过高会导致性能下降。建议使用较低的值,例如 12;否则,在建议调用中花费的时间可能会超过在查询执行中花费的时间。

separator

用于在双字母组字段中分隔词语的分隔符。如果未设置,则使用空格字符作为分隔符。

size

为每个单独的查询词语生成的候选数量。较小的数字,例如 35,通常会产生良好的结果。提高此值可以显示具有更高编辑距离的词语。默认值为 5

analyzer

设置分析器以分析建议文本。默认情况下使用通过 field 传递的建议字段的搜索分析器。

shard_size

设置从每个单独的分片中检索的建议词语的最大数量。在减少阶段,仅返回基于 size 选项的前 N 个建议。默认值为 5

text

设置要提供建议的文本/查询。

highlight

设置建议突出显示。如果未提供,则不会返回 highlighted 字段。如果提供,则必须包含 pre_tagpost_tag,它们将围绕更改的标记进行包装。如果连续更改多个标记,则将包装更改的标记的整个短语,而不是每个标记。

collate

检查每个建议是否与指定的 query 相匹配,以修剪索引中不存在匹配文档的建议。建议的整理查询仅在生成建议的本地分片上运行。必须指定 query,并且可以对其进行模板化。请参阅 搜索模板。当前建议会自动作为 {{suggestion}} 变量提供,应在您的查询中使用。您仍然可以指定自己的模板 params - suggestion 值将添加到您指定的变量中。此外,您可以指定一个 prune 来控制是否返回所有短语建议;当设置为 true 时,建议将具有一个额外的选项 collate_match,如果找到短语的匹配文档,则该选项将为 true,否则为 falseprune 的默认值为 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 选项,指示生成的短语是否与任何文档匹配。

平滑模型edit

phrase 建议器支持多种平滑模型,以平衡不常见词组(在索引中不存在的词组(片段))和常见词组(在索引中至少出现一次)之间的权重。可以通过将 smoothing 参数设置为以下选项之一来选择平滑模型。每个平滑模型都支持可以配置的特定属性。

stupid_backoff

一个简单的回退模型,如果更高阶计数为 0,则回退到更低阶 n-gram 模型,并通过一个常数因子对更低阶 n-gram 模型进行折扣。默认 discount0.4。Stupid Backoff 是默认模型。

laplace

一个使用加法平滑的平滑模型,其中一个常数(通常为 1.0 或更小)被添加到所有计数中,以平衡权重。默认 alpha0.5

linear_interpolation

一个平滑模型,它根据用户提供的权重(lambda)获取单字母组、双字母组和三字母组的加权平均值。线性插值没有任何默认值。必须提供所有参数(trigram_lambdabigram_lambdaunigram_lambda)。

POST test/_search
{
  "suggest": {
    "text" : "obel prize",
    "simple_phrase" : {
      "phrase" : {
        "field" : "title.trigram",
        "size" : 1,
        "smoothing" : {
          "laplace" : {
            "alpha" : 0.7
          }
        }
      }
    }
  }
}

候选生成器edit

phrase 建议器使用候选生成器来生成给定文本中每个词语的可能词语列表。单个候选生成器类似于为文本中的每个单独词语调用的 term 建议器。生成器的输出随后与来自其他词语的候选一起评分,以生成建议候选。

目前只支持一种类型的候选生成器,即 direct_generator。短语建议 API 在 direct_generator 键下接受一个生成器列表;列表中的每个生成器都会在原始文本中的每个词语上调用。

直接生成器edit

直接生成器支持以下参数

field

要从中获取候选建议的字段。这是一个必需的选项,需要在全局或每个建议中设置。

size

每个建议文本标记要返回的最大更正数量。

suggest_mode

建议模式控制在每个分片上生成的建议中包含哪些建议。除了 always 之外的所有值都可以被认为是对生成更少建议以在每个分片上进行测试的优化,并且在组合每个分片上生成的建议时不会重新检查。因此,missing 将为在不包含它们的碎片上的词语生成建议,即使其他碎片包含它们也是如此。这些应该使用 confidence 进行过滤。可以指定三个可能的值

  • missing:仅为不在分片中的词语生成建议。这是默认值。
  • popular:仅建议在分片上比原始词语在更多文档中出现的词语。
  • always:根据建议文本中的术语建议任何匹配的建议。

max_edits

候选建议为了被视为建议可以具有的最大编辑距离。只能是 1 到 2 之间的值。任何其他值都会导致抛出错误请求错误。默认为 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_filterpost_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_filterpost_filter 也可以用于在生成候选后注入同义词。例如,对于查询 captain usq,我们可能会为词语 usq 生成一个候选 usa,它是 america 的同义词。这使我们能够向用户呈现 captain america,如果此短语得分足够高。

完成建议器edit

completion 建议器提供自动完成/边输入边搜索功能。这是一个导航功能,可以指导用户在输入时找到相关结果,从而提高搜索精度。它不适用于拼写纠正或类似于 termphrase 建议器的“您是否要查找”功能。

理想情况下,自动完成功能应该与用户输入一样快,以便提供与用户已输入内容相关的即时反馈。因此,completion 建议器针对速度进行了优化。建议器使用能够快速查找的数据结构,但构建成本高且存储在内存中。

映射edit

要使用 completion 建议器,请将要从中生成建议的字段映射为类型 completion。这将为快速完成索引字段值。

response = client.indices.create(
  index: 'music',
  body: {
    mappings: {
      properties: {
        suggest: {
          type: 'completion'
        }
      }
    }
  }
)
puts response
PUT music
{
  "mappings": {
    "properties": {
      "suggest": {
        "type": "completion"
      }
    }
  }
}

completion 字段的参数edit

completion 字段接受以下参数

analyzer

要使用的索引分析器,默认为 simple

search_analyzer

要使用的搜索分析器,默认为 analyzer 的值。

preserve_separators

保留分隔符,默认为 true。如果禁用,您可能会发现一个以 Foo Fighters 开头的字段,如果您建议 foof

preserve_position_increments

启用位置增量,默认为 true。如果禁用并使用停用词分析器,您可能会得到一个以 The Beatles 开头的字段,如果您建议 b注意: 您也可以通过索引两个输入 BeatlesThe Beatles 来实现这一点,无需更改简单分析器,如果您能够丰富您的数据。

max_input_length

限制单个输入的长度,默认为 50 个 UTF-16 代码点。此限制仅在索引时使用,以减少每个输入字符串的总字符数,以防止大量输入使底层数据结构膨胀。大多数用例不会受到默认值的影响,因为前缀完成很少会超过几个字符长的前缀。

索引edit

您可以像索引任何其他字段一样索引建议。建议由一个 input 和一个可选的 weight 属性组成。 input 是建议查询匹配的预期文本,而 weight 决定建议的评分方式。索引建议如下

response = client.index(
  index: 'music',
  id: 1,
  refresh: true,
  body: {
    suggest: {
      input: [
        'Nevermind',
        'Nirvana'
      ],
      weight: 34
    }
  }
)
puts response
PUT music/_doc/1?refresh
{
  "suggest" : {
    "input": [ "Nevermind", "Nirvana" ],
    "weight" : 34
  }
}

支持以下参数

input

要存储的输入,可以是字符串数组或单个字符串。此字段是必需的。

此值不能包含以下 UTF-16 控制字符

  • \u0000(空)
  • \u001f(信息分隔符一)
  • \u001e(信息分隔符二)

权重

一个正整数或包含正整数的字符串,用于定义权重并允许您对建议进行排名。此字段是可选的。

您可以为文档索引多个建议,如下所示

response = client.index(
  index: 'music',
  id: 1,
  refresh: true,
  body: {
    suggest: [
      {
        input: 'Nevermind',
        weight: 10
      },
      {
        input: 'Nirvana',
        weight: 3
      }
    ]
  }
)
puts response
PUT music/_doc/1?refresh
{
  "suggest": [
    {
      "input": "Nevermind",
      "weight": 10
    },
    {
      "input": "Nirvana",
      "weight": 3
    }
  ]
}

您可以使用以下简写形式。请注意,您不能在简写形式中为建议指定权重。

response = client.index(
  index: 'music',
  id: 1,
  refresh: true,
  body: {
    suggest: [
      'Nevermind',
      'Nirvana'
    ]
  }
)
puts response
PUT music/_doc/1?refresh
{
  "suggest" : [ "Nevermind", "Nirvana" ]
}

查询编辑

建议的工作方式与往常一样,只是您必须将建议类型指定为 completion。建议是近乎实时的,这意味着新的建议可以通过 刷新 来显示,并且一旦删除的文档将永远不会显示。此请求

response = client.search(
  index: 'music',
  pretty: true,
  body: {
    suggest: {
      "song-suggest": {
        prefix: 'nir',
        completion: {
          field: 'suggest'
        }
      }
    }
  }
)
puts response
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 端点上使用建议确实支持

response = client.search(
  index: 'music',
  body: {
    _source: 'suggest',
    suggest: {
      "song-suggest": {
        prefix: 'nir',
        completion: {
          field: 'suggest',
          size: 5
        }
      }
    }
  }
)
puts response
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 来修改此行为。设置后,此选项会从结果中过滤掉具有重复建议的文档。

response = client.search(
  index: 'music',
  pretty: true,
  body: {
    suggest: {
      "song-suggest": {
        prefix: 'nor',
        completion: {
          field: 'suggest',
          skip_duplicates: true
        }
      }
    }
  }
)
puts response
POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "prefix": "nor",
      "completion": {
        "field": "suggest",
        "skip_duplicates": true
      }
    }
  }
}

当设置为 true 时,此选项可能会减慢搜索速度,因为需要访问更多建议才能找到前 N 个建议。

模糊查询编辑

完成建议器还支持模糊查询,这意味着您可以在搜索中输入错别字,但仍然可以获得结果。

response = client.search(
  index: 'music',
  pretty: true,
  body: {
    suggest: {
      "song-suggest": {
        prefix: 'nor',
        completion: {
          field: 'suggest',
          fuzzy: {
            fuzziness: 2
          }
        }
      }
    }
  }
)
puts response
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

正则表达式查询编辑

完成建议器还支持正则表达式查询,这意味着您可以将前缀表示为正则表达式

response = client.search(
  index: 'music',
  pretty: true,
  body: {
    suggest: {
      "song-suggest": {
        regex: 'n[ever|i]r',
        completion: {
          field: 'suggest'
        }
      }
    }
  }
)
puts response
POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "regex": "n[ever|i]r",
      "completion": {
        "field": "suggest"
      }
    }
  }
}

正则表达式查询可以采用特定的正则表达式参数。支持以下参数

flags

可能的标志是 ALL(默认)、ANYSTRINGCOMPLEMENTEMPTYINTERSECTIONINTERVALNONE。有关其含义,请参阅 regexp-语法

max_determinized_states

正则表达式很危险,因为很容易意外地创建一个看似无害的正则表达式,但需要指数级的内部确定性自动机状态(以及相应的 RAM 和 CPU)才能让 Lucene 执行。Lucene 使用 max_determinized_states 设置(默认为 10000)来防止这种情况。您可以提高此限制以允许执行更复杂的正则表达式。

上下文建议器编辑

完成建议器会考虑索引中的所有文档,但通常希望通过某些条件过滤和/或提升建议。例如,您想根据某些艺术家过滤建议的歌曲标题,或者想根据歌曲类型提升歌曲标题。

为了实现建议过滤和/或提升,您可以在配置完成字段时添加上下文映射。您可以为完成字段定义多个上下文映射。每个上下文映射都有一个唯一的名称和一个类型。有两种类型:categorygeo。上下文映射在字段映射的 contexts 参数下配置。

在索引和查询启用上下文的完成字段时,必须提供上下文。

完成字段上下文映射的最大允许数量为 10。

以下定义了类型,每种类型都有两个完成字段的上下文映射

response = client.indices.create(
  index: 'place',
  body: {
    mappings: {
      properties: {
        suggest: {
          type: 'completion',
          contexts: [
            {
              name: 'place_type',
              type: 'category'
            },
            {
              name: 'location',
              type: 'geo',
              precision: 4
            }
          ]
        }
      }
    }
  }
)
puts response

response = client.indices.create(
  index: 'place_path_category',
  body: {
    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'
        }
      }
    }
  }
)
puts response
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_typecategory 上下文,其中类别必须与建议一起发送。

定义了一个名为 locationgeo 上下文,其中类别必须与建议一起发送。

定义了一个名为 place_typecategory 上下文,其中类别从 cat 字段中读取。

定义了一个名为 locationgeo 上下文,其中类别从 loc 字段中读取。

添加上下文映射会增加完成字段的索引大小。完成索引完全驻留在堆中,您可以使用 索引统计信息 监控完成字段索引大小。

类别上下文编辑

category 上下文允许您在索引时将一个或多个类别与建议关联起来。在查询时,可以通过其关联的类别过滤和提升建议。

映射设置类似于上面的 place_type 字段。如果定义了 path,则类别将从文档中的该路径读取,否则必须像这样在建议字段中发送

response = client.index(
  index: 'place',
  id: 1,
  body: {
    suggest: {
      input: [
        "timmy's",
        'starbucks',
        'dunkin donuts'
      ],
      contexts: {
        place_type: [
          'cafe',
          'food'
        ]
      }
    }
  }
)
puts response
PUT place/_doc/1
{
  "suggest": {
    "input": [ "timmy's", "starbucks", "dunkin donuts" ],
    "contexts": {
      "place_type": [ "cafe", "food" ]                    
    }
  }
}

这些建议将与 cafefood 类别相关联。

如果映射具有 path,则以下索引请求足以添加类别

response = client.index(
  index: 'place_path_category',
  id: 1,
  body: {
    suggest: [
      "timmy's",
      'starbucks',
      'dunkin donuts'
    ],
    cat: [
      'cafe',
      'food'
    ]
  }
)
puts response
PUT place_path_category/_doc/1
{
  "suggest": ["timmy's", "starbucks", "dunkin donuts"],
  "cat": ["cafe", "food"] 
}

这些建议将与 cafefood 类别相关联。

如果上下文映射引用另一个字段,并且类别被显式索引,则建议将使用两组类别进行索引。

类别查询编辑

可以通过一个或多个类别过滤建议。以下通过多个类别过滤建议

response = client.search(
  index: 'place',
  pretty: true,
  body: {
    suggest: {
      place_suggestion: {
        prefix: 'tim',
        completion: {
          field: 'suggest',
          size: 10,
          contexts: {
            place_type: [
              'cafe',
              'restaurants'
            ]
          }
        }
      }
    }
  }
)
puts response
POST place/_search?pretty
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "place_type": [ "cafe", "restaurants" ]
        }
      }
    }
  }
}

如果在查询中设置了多个类别或类别上下文,它们将被合并为析取。这意味着如果建议包含至少一个提供的上下文值,则建议匹配。

具有某些类别的建议可以比其他建议获得更高的提升。以下通过类别过滤建议,并额外提升与某些类别相关的建议

response = client.search(
  index: 'place',
  pretty: true,
  body: {
    suggest: {
      place_suggestion: {
        prefix: 'tim',
        completion: {
          field: 'suggest',
          size: 10,
          contexts: {
            place_type: [
              {
                context: 'cafe'
              },
              {
                context: 'restaurants',
                boost: 2
              }
            ]
          }
        }
      }
    }
  }
)
puts response
POST place/_search?pretty
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "place_type": [                             
            { "context": "cafe" },
            { "context": "restaurants", "boost": 2 }
          ]
        }
      }
    }
  }
}

上下文查询过滤器与类别 caferestaurants 相关的建议,并将与 restaurants 相关的建议提升 2 倍。

除了接受类别值之外,上下文查询还可以由多个类别上下文子句组成。以下参数适用于 category 上下文子句

context

要过滤/提升的类别的值。这是强制性的。

boost

建议分数应提升的因子,分数通过将提升乘以建议权重来计算,默认为 1

prefix

类别值是否应被视为前缀。例如,如果设置为 true,则可以通过指定 type 的类别前缀来过滤 type1type2 等类别。默认为 false

如果一个建议条目匹配多个上下文,最终得分将被计算为任何匹配上下文产生的最高得分。

地理位置上下文编辑

一个 geo 上下文允许您在索引时将一个或多个地理点或地理哈希与建议关联。在查询时,如果建议在指定地理位置的特定距离内,则可以对其进行过滤和提升。

在内部,地理点被编码为具有指定精度的地理哈希。

地理映射编辑

除了 path 设置外,geo 上下文映射还接受以下设置

精度

这定义了要索引的地理哈希的精度,可以指定为距离值 (5m, 10km 等),或作为原始地理哈希精度 (1..12)。默认值为原始地理哈希精度值 6

索引时的 precision 设置设置了查询时可以使用的最大地理哈希精度。

索引地理上下文编辑

geo 上下文可以通过建议显式设置,也可以通过 path 参数从文档中的地理点字段索引,类似于 category 上下文。将多个地理位置上下文与一个建议相关联,将为每个地理位置索引该建议。以下示例索引了一个具有两个地理位置上下文的建议

response = client.index(
  index: 'place',
  id: 1,
  body: {
    suggest: {
      input: "timmy's",
      contexts: {
        location: [
          {
            lat: 43.6624803,
            lon: -79.3863353
          },
          {
            lat: 43.6624718,
            lon: -79.3873227
          }
        ]
      }
    }
  }
)
puts response
PUT place/_doc/1
{
  "suggest": {
    "input": "timmy's",
    "contexts": {
      "location": [
        {
          "lat": 43.6624803,
          "lon": -79.3863353
        },
        {
          "lat": 43.6624718,
          "lon": -79.3873227
        }
      ]
    }
  }
}
地理位置查询编辑

建议可以根据它们与一个或多个地理点的距离进行过滤和提升。以下示例过滤了位于编码地理哈希所代表的区域内的建议

response = client.search(
  index: 'place',
  body: {
    suggest: {
      place_suggestion: {
        prefix: 'tim',
        completion: {
          field: 'suggest',
          size: 10,
          contexts: {
            location: {
              lat: 43.662,
              lon: -79.38
            }
          }
        }
      }
    }
  }
)
puts response
POST place/_search
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "location": {
            "lat": 43.662,
            "lon": -79.380
          }
        }
      }
    }
  }
}

当查询时指定了精度较低的地理位置时,将考虑位于该区域内的所有建议。

如果在查询中设置了多个类别或类别上下文,它们将被合并为析取。这意味着如果建议包含至少一个提供的上下文值,则建议匹配。

位于地理哈希所代表的区域内的建议也可以比其他建议获得更高的提升,如下所示

response = client.search(
  index: 'place',
  pretty: true,
  body: {
    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
              }
            ]
          }
        }
      }
    }
  }
)
puts response
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
            }
          ]
        }
      }
    }
  }
}

上下文查询过滤了位于精度为 *2* 的 *(43.662, -79.380)* 的地理哈希所代表的地理位置下的建议,并将位于精度为 *6* 的 *(43.6624803, -79.3863353)* 的地理哈希表示下的建议提升了 2 倍。

如果一个建议条目匹配多个上下文,最终得分将被计算为任何匹配上下文产生的最高得分。

除了接受上下文值外,上下文查询还可以由多个上下文子句组成。以下参数适用于 geo 上下文子句

context

一个地理点对象或一个地理哈希字符串,用于通过它过滤或提升建议。这是必需的。

boost

建议分数应提升的因子,分数通过将提升乘以建议权重来计算,默认为 1

精度

用于编码查询地理点的地理哈希的精度。可以指定为距离值 (5m, 10km 等),或作为原始地理哈希精度 (1..12)。默认值为索引时的精度级别。

邻居

接受一个精度值数组,这些精度值用于考虑相邻的地理哈希。精度值可以是距离值 (5m, 10km 等) 或原始地理哈希精度 (1..12)。默认值为为索引时的精度级别生成邻居。

精度字段不会导致距离匹配。指定距离值,如 10km,只会导致一个表示该大小的瓦片的地理哈希精度值。精度将用于将搜索地理点编码为一个地理哈希瓦片,用于完成匹配。这样做的结果是,即使非常靠近搜索点,但位于该瓦片之外的点也不会匹配。降低精度或增加距离可以降低发生这种情况的风险,但不能完全消除。

返回建议器的类型编辑

有时您需要知道建议器的确切类型才能解析其结果。可以使用 typed_keys 参数更改响应中的建议器名称,以便在它前面加上它的类型。

考虑以下具有两个建议器 termphrase 的示例

response = client.search(
  typed_keys: true,
  body: {
    suggest: {
      text: 'some test mssage',
      "my-first-suggester": {
        term: {
          field: 'message'
        }
      },
      "my-second-suggester": {
        phrase: {
          field: 'message'
        }
      }
    }
  }
)
puts response
POST _search?typed_keys
{
  "suggest": {
    "text" : "some test mssage",
    "my-first-suggester" : {
      "term" : {
        "field" : "message"
      }
    },
    "my-second-suggester" : {
      "phrase" : {
        "field" : "message"
      }
    }
  }
}

在响应中,建议器名称将分别更改为 term#my-first-suggesterphrase#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 前缀。