为什么使用NEST使用自定义分析器排序的嵌套ElasticSearch返回无效结果? [英] Why does my sorted nested ElasticSearch with custom analyzer using NEST return invalid result?
问题描述
使用elasticSearch v6.2.4,我想根据HMI中的用户选择对结果进行排序.
Using elasticSearch v6.2.4 I want to sort my results based on user selection in the HMI.
这对于我的SearchableSituation中的大多数元素都是成功的,但对InvolvedVessels成员而言却不是.
This is successful for most of the elements in my SearchableSituation but not for the member InvolvedVessels.
我对ES还是很陌生,读了很多书后,我对查询和排序等所有可能的变体感到有些迷茫.
I'm quite new to ES, and having read around I'm feeling a bit lost with all the possible variants of Querying and sorting etc..
该课程的简短版本:
public class SearchableSituation : IEquatable<SearchableSituation>
{
//Other members
public IEnumerable<SearchableInvolvedVessel> InvolvedVessels { get; set; }
}
该字段的映射在这里完成:
The mapping of the field is done here:
private static TypeMappingDescriptor<SearchableSituation> ConfigureNestedSearchableSituation(TypeMappingDescriptor<SearchableSituation> mapping)
{
return mapping
.AutoMap()
.Properties(ps => ps
.Text(t => t
.Name(n => n.SituationId)
.Analyzer("keyword"))
.Nested<SearchableInvolvedVessel>(ConfigureSearchableInvolvedVessel); // More Nested items in actual code removed for simplicity
}
private static NestedPropertyDescriptor<SearchableSituation, SearchableInvolvedVessel> ConfigureSearchableInvolvedVessel(NestedPropertyDescriptor<SearchableSituation, SearchableInvolvedVessel> nestedPropertyDescriptor)
{
return nestedPropertyDescriptor
.AutoMap()
.Properties(np => np
.Text(t => t
.Name(nn => nn.VesselName)
.Fields(f => f
.Text(tk => tk
.Name("singleTerm") //adding sub-field with keyword analyzer to index 'Name' property to include single term search when using phrase_prefix queries.
.Analyzer("keywordWithCaseIgnore"))))
.Text(t => t
.Name(nn => nn.VesselId)
.Analyzer("keyword")
)
)
.Name(nn => nn.InvolvedVessels);
}
将索引定义为(在此处删除了一些项目以减小尺寸):
With the index defined as (removed some items to reduce size here):
{
"situationsindex": {
"aliases": {},
"mappings": {
"searchablesituation": {
"properties": {
"involvedVessels": {
"type": "nested",
"properties": {
"callSign": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"isRiskRole": {
"type": "boolean"
},
"vesselName": {
"type": "text",
"fields": {
"singleTerm": {
"type": "text",
"analyzer": "keywordWithCaseIgnore"
}
}
}
}
},
"situationId": {
"type": "text",
"analyzer": "keyword"
},
"status": {
"type": "integer"
},
}
}
},
"settings": {
"index": {
"number_of_shards": "5",
"provided_name": "situationsindex",
"creation_date": "1577957440559",
"analysis": {
"normalizer": {
"lowercaseNormalizer": {
"filter": [
"lowercase"
],
"type": "custom"
}
},
"analyzer": {
"keywordWithCaseIgnore": {
"filter": [
"lowercase"
],
"type": "custom",
"tokenizer": "keyword"
}
}
},
"number_of_replicas": "1",
"uuid": "-UoM84BxQwiUdT6QLL04Eg",
"version": {
"created": "6020499"
}
}
}
}
}
我正在尝试建立这样的查询:
I'm trying to build my query as such:
var sortedResult = await _client.SearchAsync<SearchableSituation>(s => s
.Index(_situationIndexer.IndexName)
.From(message.Query.SearchResultsFrom)
.Size(message.Query.SearchResultsSize)
.Sort(sort => sort.Ascending(f => f.Status)
.Field(x => x.Nested(y => y.Path(p => p.InvolvedVessels))
.Field(v => v.InvolvedVessels.First().VesselName.Suffix("keyword"))
.Field("name.singleTerm")
.Order(sortOrder)))
.Query(q => q
.Bool(m => m
.Must(queries))));
.Query是一个可选过滤器,默认情况下为空(返回所有元素).
Where .Query is an optional filter which by default is empty (returning all elements).
返回:
Invalid NEST response built from a unsuccessful low level call on POST: /situationsindex/searchablesituation/_search?typed_keys=true # Audit trail of this API call: - [1] BadResponse: Node: http://localhost:9200/ Took: 00:00:00.0030001 # OriginalException: System.Net.WebException: The remote server returned an error: (400) Bad Request. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Elasticsearch.Net.HttpConnection.d__14`1.MoveNext() in C:\Users\russ\source\elasticsearch-net-master\src\Elasticsearch.Net\Connection\HttpConnection.cs:line 242 # Request: # Response:
尝试了很多Path,Field和Suffix选项的变体,但没有成功,我开始感到有些卡住.
Having a tried a number of variants of Path, Field and Suffix options without success I'm beginng to feel a bit stuck.
任何人都可以指导我解决我的问题吗?
Can anyone guide me on where I'm going wrong?
推荐答案
因此,在VesselName映射中添加一个附加字段会为我提供有效的结果
So, adding an additional field to VesselName Mapping yielded me a valid result
.Text(t => t
.Name(nn => nn.VesselName)
.Fields(f => f
.Text(tk => tk
.Name("singleTerm") //adding sub-field with keyword analyzer to index 'Name' property to include single term search when using phrase_prefix queries.
.Analyzer("keywordWithCaseIgnore"))//))
.Keyword(k => k //<--- These two lines
.Name("keyword")))) //<---
但是,向.First()子句添加条件仍然会产生无效的结果.
However, adding a condition to the .First() clause still yield an invalid result.
.Sort(sort => sort.Ascending(f => f.Status)
.Field(x => x.Nested(y => y.Path(p => p.InvolvedVessels))
.Field(v => v.InvolvedVessels.First(iv => iv.IsRiskRole).VesselName.Suffix("keyword"))
.Order(sortOrder)))
.Query(q => q
.Bool(m => m
.Must(queries))));
这篇关于为什么使用NEST使用自定义分析器排序的嵌套ElasticSearch返回无效结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!