我是Elasticsearch的完整入门者,我一直在尝试使用Elasticsearch的完成建议程序,该建议程序使用Nest来自动完成属性。
这是我的映射(如此处提及:):
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>(Contact具有一个名为CompanyName的属性,Contact是一个抽象类,Person和Company都是其具体实现)。搜索抛出异常, 表明ElasticSearchException [Field [companyName]不是完成建议字段] 。查询如下所示:
IndexMany
IEnumberable<Contact>
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();
我在这里做错了什么,我SuggestCompletion只看了Nest的测试,但没有太多帮助,这意味着该测试仅描述了如何获取建议,而没有说明如何为RecommendationCompletion设置索引映射。
SuggestCompletion
我也尝试设立edgeNgram在此提到的标记生成器后,但是,不能进行有作为。
edgeNgram
关于如何进行的任何方向或示例都将大有帮助。
更新
您尝试创建一个名称为“ companyName.completion”的属性,但是在该位置该属性无效,它将使用最后一个标记“completion”。因此,它实际上映射了一个称为完成的字段…。尝试将调用更改为:.Name(p => p.CompanyName)
.Name(p => p.CompanyName)
其他观察
您可以为,Contact但在建立索引时使用Person和Company类型。
Contact
Person
Company
用您映射的Elasticsearch术语:
/index/contact/
但您的文档将进入:
/index/person/ 和 /index/company
/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并且将知道如何向您返回文档的协变列表。
/index/person
因此,您可以result.Documents.OfType<Person>()在上一个呼叫之后执行。
result.Documents.OfType<Person>()