Nest SuggestCompletion 用法,抛出“不是完成建议字段”异常
Posted
技术标签:
【中文标题】Nest SuggestCompletion 用法,抛出“不是完成建议字段”异常【英文标题】:Nest SuggestCompletion usage, throws 'is not a completion suggest field' exception 【发布时间】:2014-01-29 14:13:17 【问题描述】:我是 elasticsearch 的初学者,我一直在尝试使用 elasticsearch 的完成建议,使用 Nest 自动完成属性。
这是我的映射(如here: 所述):
var createResult = client.CreateIndex(indexName, index => index
.AddMapping<Contact>(tmd => tmd
.Properties(props => props
.Completion(s =>
s.Name(p => p.CompanyName.Suffix("completion"))
.IndexAnalyzer("standard")
.SearchAnalyzer("standard")
.MaxInputLength(20)
.Payloads()
.PreservePositionIncrements()
.PreserveSeparators())
)
)
);
var resultPerson = client.IndexMany(documents.OfType<Person>(), new SimpleBulkParameters Refresh = true );
var resultCompany = client.IndexMany(documents.OfType<Company>(), new SimpleBulkParameters Refresh = true );
在索引时,我只是使用IndexMany
方法并传递IEnumberable<Contact>
(联系人有一个名为CompanyName 的属性,Contact 是一个抽象类,Person 和Company 都是它的具体实现)。搜索引发异常,提示 ElasticSearchException[Field [companyName] 不是完成建议字段]。查询如下所示:
SearchDescriptor<Contact> descriptor = new SearchDescriptor<Contact>();
descriptor = descriptor.SuggestCompletion("suggest", c => c.OnField(f => f.CompanyName).Text(q));
var result = getElasticClientInstance("contacts").Search<Contact>(body => descriptor);
string qe = result.ConnectionStatus.ToString();
我在这里做错了什么,我查看了 Nest 在 SuggestCompletion
上的测试,但没有太大帮助,这意味着该测试仅描述了如何获取建议,而不描述如何为 SuggestCompletion 设置索引映射。
我还尝试设置edgeNgram
标记器,如post 中所述,但也无法继续进行。
任何关于如何进行的指导或示例都会有很大帮助。
【问题讨论】:
【参考方案1】:更新
您尝试创建一个名为“companyName.completion”的属性,但在该位置它无效,它将使用最后一个标记“completion”。所以它实际上映射了一个名为完成的字段....尝试将调用更改为:.Name(p => p.CompanyName)
其他意见
您为Contact
指定了一个映射,但在编制索引时您使用Person
和Company
类型。
在您映射的弹性搜索术语中:
/index/contact/
但您的文件将进入:
/index/person/
和 /index/company
NEST 不会自动映射特定类的所有实现,并且 elasticsearch 无法知道这三个是相关的。
我会将映射重构为一个方法,并为所有涉及的类型调用它。
var createResult = client.CreateIndex(indexName, index => index
.AddMapping<Contact>(tmd => MapContactCompletionFields(tmd))
.AddMapping<Person>(tmd => MapContactCompletionFields(tmd))
.AddMapping<Company>(tmd => MapContactCompletionFields(tmd))
);
private RootObjectMappingDescriptor<TContact> MapContactCompletionFields<TContact>(
RootObjectMappingDescriptor<TContact> tmd)
where TContact : Contact
return tmd.Properties(props => props
.Completion(s => s
.Name(p => p.CompanyName.Suffix("completion"))
.IndexAnalyzer("standard")
.SearchAnalyzer("standard")
.MaxInputLength(20)
.Payloads()
.PreservePositionIncrements()
.PreserveSeparators()
)
);
该方法返回描述符,因此您可以进一步链接它。
然后当你搜索联系人时:
var result = getElasticClientInstance("contacts").Search<Contact>(
body => descriptor
.Types(typeof(Person), typeof(Company))
);
该类型提示将导致搜索查找/index/person
和/index/company
,并且会知道如何返回一个协变的文档列表。
所以你可以在上次通话后做result.Documents.OfType<Person>()
。
【讨论】:
感谢您的回复。我仍然遇到同样的问题:ElasticSearchException[Field [companyName] 不是完成建议字段]。这是我的查询:StatusCode: InternalServerError, Method: POST, Url: http://192.168.1.105:9200/contacts/people/_search, Request: "suggest": "suggest": "text": "land", "completion": "field": "companyName"
。而且我不确定“人”是如何被视为“人”的,我没有提到这一点。公司也一样,它显示为公司,联系人显示为联系人。查询中有两个“建议”吗?
您能否将192.168.1.105:9200/contacts/_mapping 的回复粘贴到您的答案中?还是作为 github 上的要点?
啊,我知道发生了什么,您正在尝试创建一个名为“companyName.completion”的属性,但在该位置它无效,它将使用最后一个标记“completion”。所以它实际上映射了一个名为completion
....的字段尝试将调用更改为:.Name(p => p.CompanyName)
哇,成功了,谢谢。现在,结果显示所有对象的总命中数,它应该只拉那些具有此文本的对象吗?并且输出根据我的查询提出了建议,我不确定如何将建议显示给用户,我假设我需要查询建议字典。 gist.github.com/BharathChandra/8708544
是的,NEST 目前仅支持 _search
端点上的建议,因此在搜索描述符 .Size(0)
上设置 .Size(0)
端点支持正在开发中!您可以将答案标记为已接受吗?以上是关于Nest SuggestCompletion 用法,抛出“不是完成建议字段”异常的主要内容,如果未能解决你的问题,请参考以下文章