我正在尝试使用NEST客户端进行自动完成。
代码如下:
Poco(浓缩):
public class Course
{
[ElasticProperty(Name="id")]
public int ID { get; set; }
public string Name { get; set; }
[ElasticProperty(Type = FieldType.Completion)]
public CompletionField Suggest { get; set; }
public Course(sm.Models.Course c)
{
if (c != null)
{
this.ID = c.ID;
this.Name = c.Name;
this.Suggest = new CompletionField
{
Input = new List<string>(this.Name.Split(' ')) { this.Name },
Output = this.Name,
Payload = new
{
id = this.Name
},
Weight = 1
};
}
}
}
索引:
Client.CreateIndex("myindex", c => c
.NumberOfReplicas(1)
.NumberOfShards(5)
.Settings(s => s
.Add("merge.policy.merge_factor", "10")
.Add("search.slowlog.threshold.fetch.warn", "1s")
)
.AddMapping<Course>(m => m.MapFromAttributes()
.Properties(props => props
.Completion(s=>s
.Name(p=>p.Suggest)
.IndexAnalyzer("simple")
.SearchAnalyzer("simple")
.MaxInputLength(20)
.Payloads()
.PreservePositionIncrements()
.PreserveSeparators()
)
)
));
我的建议查询:
GET _suggest
{
"course-suggest": {
"text": "Nothilfe",
"completion": {
"field": "suggest",
"size": 10
}
}
}
导致此错误:
"failures": [
{
"shard": 1,
"index": "myindex",
"status": "INTERNAL_SERVER_ERROR",
"reason": {
"type": "exception",
"reason": "failed to execute suggest",
"caused_by": {
"type": "exception",
"reason": "Field [suggest] is not a completion suggest field"
}
}
}
为什么我的建议字段未被识别为完成字段?
GET _mapping / course
"suggest": {
"properties": {
"input": {
"type": "string"
},
"output": {
"type": "string"
},
"payload": {
"properties": {
"id": {
"type": "string"
}
}
},
"weight": {
"type": "long"
}
}
答案 0 :(得分:3)
您可能会收到此错误的原因有几个,但最明显的原因是索引course
中类型myindex
的映射与您查询的查询有关。 #39;重新发送。
您可以使用
轻松检查类型的映射curl -XGET "http://localhost:9200/myindex/course/_mapping"
应该看起来像
{
"myindex": {
"mappings": {
"course": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"suggest": {
"type": "completion",
"analyzer": "simple",
"payloads": true,
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 20
}
}
}
}
}
}
如果它不需要解决此问题,可以通过删除索引中的类型并重新创建(或完全删除索引并重新创建),或者通过使用正确的映射创建新索引如果您想 *尝试* 以保留您已有的任何数据(这可能是也可能不存在),并从旧索引复制文档。
以下内容将按预期创建索引并执行您尝试运行的suggest
查询。请注意,我已将查询范围限定为仅针对索引myindex
运行。类型
public class Course
{
[ElasticProperty(Name = "id")]
public int ID { get; set; }
public string Name { get; set; }
[ElasticProperty(Type = FieldType.Completion)]
public CompletionField Suggest { get; set; }
public Course(Course c)
{
if (c != null)
{
this.ID = c.ID;
this.Name = c.Name;
this.Suggest = new CompletionField
{
Input = new List<string>(this.Name.Split(' ')) { this.Name },
Output = this.Name,
Payload = new
{
id = this.Name
},
Weight = 1
};
}
}
}
// I'm guessing CompletionField looks something like this?
public class CompletionField
{
public List<string> Input { get; set; }
public string Output { get; set; }
public object Payload { get; set; }
public double Weight { get; set; }
}
并创建索引和查询
void Main()
{
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.ExposeRawResponse(true)
.SetConnectionStatusHandler(response =>
{
// log out the requests
if (response.Request != null)
{
Console.WriteLine("{0} {1} \n{2}\n", response.RequestMethod.ToUpperInvariant(), response.RequestUrl,
Encoding.UTF8.GetString(response.Request));
}
else
{
Console.WriteLine("{0} {1}\n", response.RequestMethod.ToUpperInvariant(), response.RequestUrl);
}
if (response.ResponseRaw != null)
{
Console.WriteLine("{0}\n{1}\n\n{2}\n", response.HttpStatusCode, Encoding.UTF8.GetString(response.ResponseRaw), new String('-', 30));
}
else
{
Console.WriteLine("{0}\n\n{1}\n", response.HttpStatusCode, new String('-', 30));
}
});
var client = new ElasticClient(settings);
var indexResponse = client.CreateIndex("myindex", c => c
.NumberOfReplicas(1)
.NumberOfShards(5)
.Settings(s => s
.Add("merge.policy.merge_factor", "10")
.Add("search.slowlog.threshold.fetch.warn", "1s")
)
.AddMapping<Course>(m => m.MapFromAttributes()
.Properties(props => props
.Completion(s => s
.Name(p => p.Suggest)
.IndexAnalyzer("simple")
.SearchAnalyzer("simple")
.MaxInputLength(20)
.Payloads()
.PreservePositionIncrements()
.PreserveSeparators()
)
)
));
// give Elasticsearch some time to initialize the index
Thread.Sleep(TimeSpan.FromSeconds(5));
var suggestResponse = client.Suggest<Course>(s => s
.Index("myindex")
.Completion("course-suggest", c => c
.Text("Nothilfe")
.OnField("suggest")
.Size(10)
)
);
// do something with suggestResponse
}
这会将以下内容注销到控制台
POST http://localhost:9200/myindex
{
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5,
"merge.policy.merge_factor": "10",
"search.slowlog.threshold.fetch.warn": "1s"
}
},
"mappings": {
"course": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"suggest": {
"type": "completion",
"search_analyzer": "simple",
"index_analyzer": "simple",
"payloads": true,
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_len": 20
}
}
}
}
}
200
{"acknowledged":true}
------------------------------
POST http://localhost:9200/myindex/_suggest
{
"course-suggest": {
"text": "Nothilfe",
"completion": {
"field": "suggest",
"size": 10
}
}
}
200
{"_shards":{"total":5,"successful":5,"failed":0}}
------------------------------