Why does my sorted nested ElasticSearch with custom analyzer using NEST return invalid result?

空扰寡人 提交于 2020-01-25 08:56:30

问题


Using elasticSearch v6.2.4 I want to sort my results based on user selection in the HMI.

This is successful for most of the elements in my SearchableSituation but not for the member InvolvedVessels.

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..

Short version of the class:

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))));

Where .Query is an optional filter which by default is empty (returning all elements).

Returns:

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: 

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?


回答1:


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"))))  //<---

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))));


来源:https://stackoverflow.com/questions/59561611/why-does-my-sorted-nested-elasticsearch-with-custom-analyzer-using-nest-return-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!