我正在尝试使用Elasticsearch.net创建自动完成功能,但我一直收到无效响应。
但是无法弄清楚为什么?
我的请求看起来像这样
var descriptor = new SearchDescriptor<EmployeeDocument>()
.Index("employees").Type("employee").From(page - 1).Size(pageSize)
.Suggest(
s => s.Completion(
"my-completion-suggest",
c => c
.Field(f1 => f1.Description)
.Field(f1 => f1.empfirstname)
.Contexts(
queriesDescriptor => queriesDescriptor.Context(
"query-descriptor",
queryDescriptor => queryDescriptor.Prefix(true).Context(query)))));
var response3 = await this.client.SearchAsync<EmployeeDocument>(descriptor);
我得到的错误是
Invalid NEST response built from a unsuccessful low level call on POST: /employees/employee/_search
Audit trail of this API call:
- [1] BadResponse: Node: http://192.168.2.29:9200/ Took: 00:00:00.3543244
ServerError: ServerError: 400Type: search_phase_execution_exception Reason: "all shards failed"
这就是我调用方法的方法
var results1 = await service.SearchAsync("brenda", page, pageSize);
var results8 = await service.SearchAsync("something else", page, pageSize);
我的模型也很简单。我遗漏了一些属性
[ElasticsearchType(Name = "employee")]
public class EmployeeDocument
{
//[Text(Name = "pkempid")]
public long pkempid { get; set; }
//[Text(Name = "empfirstname")]
public string empfirstname { get; set; }
}
答案 0 :(得分:2)
Description
和empfirstname
需要映射为completion
field data types。 NEST中的CompletionField
类型可用于属性类型,该类型将通过automapping映射为completion
数据类型。
此外,完成建议者只能指定一个字段,因此将多个调用链接到.Field()
将无法按预期工作(最后一次调用将是使用的字段)。但是,您可以在针对不同字段的一个请求中指定多个建议器。但是,更常见的是,不是在映射中具有多个完成字段,而是为单个完成字段指定多个输入值。
完成建议器的用例是在键入时提供快速搜索&#34;自动完成功能,权衡可以使用text
字段数据类型执行的更复杂分析链的功能。
答案 1 :(得分:1)
好的,所以我想出了如何进行自动完成,我最终使用Edge NGram Tokenizer
我需要做的第一件事就是使用正确的过滤器设置我的索引。
var response = this.client.CreateIndex(
ElasticConfig.IndexName,
index => index.Mappings(
ms => ms.Map<EmployeeDocument>(
m => m.Properties(
p => p
.Text(t => t.Name(n => n.EmpFirstName).Analyzer("auto-complete").Fields(ff => ff.Keyword(k => k.Name("keyword"))))
.Text(t => t.Name(n => n.pkEmpID).Analyzer("auto-complete-id").Fields(ff => ff.Keyword(k => k.Name("keyword"))))
.Text(t => t.Name(n => n.Description).Analyzer("auto-complete").Fields(ff => ff.Keyword(k => k.Name("keyword")))))))
.Settings(f => f.Analysis(
analysis => analysis
.Analyzers(
analyzers => analyzers
.Custom("auto-complete", a => a.Tokenizer("standard").Filters("lowercase", "auto-complete-filter"))
.Custom("auto-complete-id", a => a.Tokenizer("standard").Filters("lowercase", "auto-complete-id-filter")))
.TokenFilters(tokenFilter => tokenFilter
.EdgeNGram("auto-complete-filter", t => t.MinGram(3).MaxGram(5))
.EdgeNGram("auto-complete-id-filter", t => t.MinGram(1).MaxGram(5))))));
然后进行实际搜索
var response = await this.client.SearchAsync<EmployeeDocument>(
x => x.Index("default-index").Type("employee").From(page - 1).Size(pageSize)
.Query(q => q
.MultiMatch(m => m
.Query(query)
.Fields(f => f
.Field(_ => _.EmpFirstName)
.Field(_ => _.pkEmpID)
.Field(_ => _.Description))))
.Highlight(
h => h.PreTags("<mark>").PostTags("</mark>").Fields(
f => f.Field(p => p.EmpFirstName),
f => f.Field(p => p.pkEmpID),
f => f.Field(p => p.Description))));