ElasticSearch 5.x向Suggestedter API(Documentation)引入了一些(突破性的)更改。最显着的变化是:面向字的完成建议(ElasticSearch 5.x)
完成建议者是面向文档的
建议都知道他们属于 文件。现在,相关文档(
_source
)是 作为完成建议的一部分返回。
总之,一切完成查询返回所有匹配文件,而不是只匹配话。这里存在的问题是如果自动完成的单词出现在多个文档中,则会出现重复。
比方说,我们有这个简单的映射:
{
"my-index": {
"mappings": {
"users": {
"properties": {
"firstName": {
"type": "text"
},
"lastName": {
"type": "text"
},
"suggest": {
"type": "completion",
"analyzer": "simple"
}
}
}
}
}
}
少数测试文档:
{
"_index": "my-index",
"_type": "users",
"_id": "1",
"_source": {
"firstName": "John",
"lastName": "Doe",
"suggest": [
{
"input": [
"John",
"Doe"
]
}
]
}
},
{
"_index": "my-index",
"_type": "users",
"_id": "2",
"_source": {
"firstName": "John",
"lastName": "Smith",
"suggest": [
{
"input": [
"John",
"Smith"
]
}
]
}
}
而且一个由这本书查询:
POST /my-index/_suggest?pretty
{
"my-suggest" : {
"text" : "joh",
"completion" : {
"field" : "suggest"
}
}
}
这将产生结果如下:
{
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"my-suggest": [
{
"text": "joh",
"offset": 0,
"length": 3,
"options": [
{
"text": "John",
"_index": "my-index",
"_type": "users",
"_id": "1",
"_score": 1,
"_source": {
"firstName": "John",
"lastName": "Doe",
"suggest": [
{
"input": [
"John",
"Doe"
]
}
]
}
},
{
"text": "John",
"_index": "my-index",
"_type": "users",
"_id": "2",
"_score": 1,
"_source": {
"firstName": "John",
"lastName": "Smith",
"suggest": [
{
"input": [
"John",
"Smith"
]
}
]
}
}
]
}
]
}
总之,对于文本“joh”的完成建议,返回了两个(2)文档 - John和他们都具有相同的text
属性值。
但是,我想收到一个(1)字。简单的东西是这样的:
{
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"my-suggest": [
{
"text": "joh",
"offset": 0,
"length": 3,
"options": [
"John"
]
}
]
}
问题:如何实现一个基于词完成建议者。没有必要返回任何文档相关的数据,因为我现在不需要它。
“完成建议”是否适合我的场景?还是应该使用完全不同的方法?
编辑: 正如你们许多人所指出的,额外的完成,只指数将是一个可行的解决方案。但是,我可以看到使用此方法的多个问题:
- 保持新索引同步。
- 自动填写后续单词可能是全球性的,而不是缩小范围。例如,假设您在附加索引中有以下词语:
"John", "Doe", "David", "Smith"
。查询"John D"
时,不完整单词的结果应为"Doe"
而不是"Doe", "David"
。
为了克服第二点,只索引单个单词是不够的,因为您还需要将所有单词映射到文档以正确缩小自动完成后续单词的范围。与此一起,您实际上遇到与查询原始索引相同的问题。因此,额外的索引不再有意义了。
为[在这个问题]在暗示(https://github.com/elastic/elasticsearch/issues/21676),这种新的行为是 “设计”并没有计划改变它。他们的建议是为完成建议者创建另一个索引。正如下面的@EdgarVonk所建议的那样。 – Val
关于当前索引的自定义查询呢?也许用独特的查询(术语聚合)为所有建议创建额外的NGram字段?至于额外的建议索引,我可以确定一些问题,这些问题实际上与您提出的解决方案相矛盾(请参阅我的更新问题)。 – alesc
当然,术语聚合也可以实现类似的目标,但它取决于您拥有的文档的负载。我不是在提出这个解决方案,埃德加和ES人(见问题)是;-) – Val