为什么使用NEST使用自定义分析器排序的嵌套ElasticSearch返回无效结果? [英] Why does my sorted nested ElasticSearch with custom analyzer using NEST return invalid result?

查看:475
本文介绍了为什么使用NEST使用自定义分析器排序的嵌套ElasticSearch返回无效结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆