5.6 建议器 (Suggesters) Elasticsearch 核心操作:搜索与查询 - 5.6 建议器 (Suggesters) 建议器 (Suggesters) 是 Elasticsearch 提供的一项强大的功能,用于提供自动完成(autocomplete)或“您是不是要找” (did-you-mean) 功能。它们允许用户在输入查询时获得实时建议,从而提高搜索体验并减少搜索错误。 5.6.1 建议器的类型 Elasticsearch 提供了多种类型的建议器,每种类型都针对不同的使用场景进行了优化: Term Suggester: 基于单个词项 (term) 给出建议。它会分析输入的词项,并根据编辑距离(例如 Levenshtein 距离)找到相似的词项。适用于简单的拼写纠正。
建议器 (Suggesters) 是 Elasticsearch 提供的一项强大的功能,用于提供自动完成(autocomplete)或“您是不是要找” (did-you-mean) 功能。它们允许用户在输入查询时获得实时建议,从而提高搜索体验并减少搜索错误。
Elasticsearch 提供了多种类型的建议器,每种类型都针对不同的使用场景进行了优化:
Term Suggester: 基于单个词项 (term) 给出建议。它会分析输入的词项,并根据编辑距离(例如 Levenshtein 距离)找到相似的词项。适用于简单的拼写纠正。
Phrase Suggester: 基于整个短语给出建议。它会考虑词项的上下文,并尝试找到更正后的短语,而不是单个词项。适用于更复杂的拼写纠正和自动完成。
Completion Suggester: 专为自动完成而设计。它使用前缀匹配,并针对速度进行了优化。它需要在索引时进行特殊配置,以构建高效的查找结构。
Context Suggester: 允许根据上下文过滤建议。例如,可以根据用户的位置、类别或任何其他相关信息来限制建议。
Term Suggester 是最基本的建议器。它通过计算输入词项与索引中词项之间的编辑距离来工作。
代码示例:
首先,创建一个包含一些文档的索引:
PUT /my_index { "mappings": { "properties": { "text": { "type": "text" } } } } POST /my_index/_doc?refresh=true { "text": "Elasticsearch is a search engine." } POST /my_index/_doc?refresh=true { "text": "I love searching with Elasticsearch." } POST /my_index/_doc?refresh=true { "text": "Elastic search is awesome." }
然后,使用 Term Suggester 进行建议:
POST /my_index/_search { "suggest": { "my_suggestion": { "text": "elasticserch", "term": { "field": "text" } } } }
响应示例:
{ "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "suggest": { "my_suggestion": [ { "text": "elasticserch", "offset": 0, "length": 12, "options": [ { "text": "elasticsearch", "score": 0.90909094, "freq": 2 } ] } ] } }
参数详解:
text: 用户输入的文本。
term: 指定使用 Term Suggester。
field: 要从中提取词项的字段。
options: 包含建议的词项,score 表示相似度,freq 表示词项在索引中出现的频率。
Term Suggester 的更多选项:
size: 要返回的最大建议数量(默认值为 5)。
sort: 排序方式,可以是 score(默认)或 frequency。
suggest_mode: 指定如何选择建议。可以是 missing (只在没有完全匹配时建议), popular (只建议比原始词项更常见的词项), 或 always (总是建议)。
max_edits: 编辑距离的最大值,默认是2。
prefix_length: 词条需要匹配的前缀最小长度,默认是1。
Phrase Suggester 考虑了词项的上下文,并尝试提供更正后的短语。它比 Term Suggester 更复杂,但也更强大。
代码示例:
POST /my_index/_search { "suggest": { "my_suggestion": { "text": "elastic serch engine", "phrase": { "field": "text" } } } }
响应示例:
{ "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "suggest": { "my_suggestion": [ { "text": "elastic serch engine", "offset": 0, "length": 19, "options": [ { "text": "elasticsearch search engine", "score": 0.07407407, "highlighted": "<em>elasticsearch</em> search engine" } ] } ] } }
参数详解:
text: 用户输入的文本。
phrase: 指定使用 Phrase Suggester。
field: 要从中提取短语的字段。
highlighted: 突出显示建议中与输入不同的部分。
Phrase Suggester 的更多选项:
gram_size: 用于构建短语的词条数量,默认是1。
real_word_error_likelihood: 一个词条拼写错误的概率,默认是0.95。
confidence: 只有当建议的得分至少是原始短语的 confidence 倍时,才返回建议。默认值为 1.0。
max_errors: 允许的最大错误数。
separator:用于分割短语的字符,默认是空格。
Phrase Suggester 使用更复杂的算法,因此性能可能比 Term Suggester 差。
Completion Suggester 专为自动完成而设计。它使用前缀匹配,并针对速度进行了优化。
代码示例:
首先,需要创建一个特殊的映射,其中包含 completion 类型的字段:
PUT /my_index { "mappings": { "properties": { "title": { "type": "text" }, "suggest": { "type": "completion", "analyzer": "standard", "search_analyzer": "standard" } } } }
然后,添加一些文档:
POST /my_index/_doc?refresh=true { "title": "Elasticsearch Complete Guide", "suggest": { "input": ["Elasticsearch Complete Guide", "Elasticsearch Guide", "Complete Guide"], "weight": 1 } } POST /my_index/_doc?refresh=true { "title": "Elasticsearch Definitive Guide", "suggest": { "input": ["Elasticsearch Definitive Guide", "Definitive Guide"], "weight": 2 } }
现在,可以使用 Completion Suggester 进行建议:
POST /my_index/_search { "suggest": { "my_suggestion": { "prefix": "elastic", "completion": { "field": "suggest", "fuzzy": { "fuzziness": "AUTO" } } } } }
响应示例:
{ "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "suggest": { "my_suggestion": [ { "text": "elastic", "offset": 0, "length": 7, "options": [ { "text": "Elasticsearch Definitive Guide", "_index": "my_index", "_id": "l649Ho0B6w3o_r9w0X-0", "_score": 2.0, "_source": { "title": "Elasticsearch Definitive Guide", "suggest": { "input": [ "Elasticsearch Definitive Guide", "Definitive Guide" ], "weight": 2 } } }, { "text": "Elasticsearch Complete Guide", "_index": "my_index", "_id": "lK49Ho0B6w3o_r9w0X-0", "_score": 1.0, "_source": { "title": "Elasticsearch Complete Guide", "suggest": { "input": [ "Elasticsearch Complete Guide", "Elasticsearch Guide", "Complete Guide" ], "weight": 1 } } } ] } ] } }
参数详解:
prefix: 用户输入的前缀。
completion: 指定使用 Completion Suggester。
field: completion 类型的字段。
fuzzy: 允许模糊匹配。
Completion Suggester 的更多选项:
size: 要返回的最大建议数量(默认值为 5)。
fuzzy: 模糊选项,允许模糊匹配。
contexts: 使用上下文过滤建议。
Completion Suggester 提供了最佳的自动完成性能,但需要在索引时进行特殊配置。
Context Suggester 允许你基于上下文信息过滤建议。这对于根据用户的位置、类别或其他相关属性提供个性化建议非常有用。
代码示例:
假设我们有一个包含书籍信息的索引,并且我们想要根据书籍的类别提供建议。
首先,创建索引和映射:
PUT /books { "mappings": { "properties": { "title": { "type": "text" }, "category": { "type": "keyword" }, "suggest": { "type": "completion", "contexts": [ { "name": "category", "type": "category" } ] } } } }
然后,添加一些文档:
POST /books/_doc?refresh=true { "title": "The Lord of the Rings", "category": "fantasy", "suggest": { "input": "The Lord of the Rings", "contexts": { "category": "fantasy" } } } POST /books/_doc?refresh=true { "title": "A Game of Thrones", "category": "fantasy", "suggest": { "input": "A Game of Thrones", "contexts": { "category": "fantasy" } } } POST /books/_doc?refresh=true { "title": "The Martian", "category": "science_fiction", "suggest": { "input": "The Martian", "contexts": { "category": "science_fiction" } } }
现在,可以使用 Context Suggester 进行建议:
POST /books/_search { "suggest": { "my_suggestion": { "prefix": "the", "completion": { "field": "suggest", "contexts": { "category": "fantasy" } } } } }
这将只返回类别为 "fantasy" 的书籍的建议。
参数详解:
contexts: 一个对象,其中键是上下文的名称,值是上下文的值。选择哪种 Suggester 取决于你的具体需求:
对于简单的拼写纠正,Term Suggester 可能就足够了。
对于更复杂的拼写纠正和自动完成,Phrase Suggester 是一个不错的选择。
对于高性能的自动完成,Completion Suggester 是最佳选择。
对于需要根据上下文进行过滤的场景,Context Suggester 非常有用。
Elasticsearch 的 Suggester 提供了一种强大的方式来改进搜索体验。通过选择合适的 Suggester 并正确配置它,你可以为用户提供准确、相关的建议,从而提高搜索效率和用户满意度。