我是弹性搜索的完全初学者,我一直在尝试使用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的索引映射。
我还尝试设置此post中提到的edgeNgram
令牌化程序,但也无法继续进行。
任何方向或如何进行的例子都会有很大帮助。
答案 0 :(得分:5)
<强>更新强>
您尝试创建名为“companyName.completion”的属性,但在该位置无效且将使用最后一个标记“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>()
。