gpt4 book ai didi

elasticsearch - 将ElasticSearch查询转换为Nest C#

转载 作者:行者123 更新时间:2023-12-02 22:47:43 35 4
gpt4 key购买 nike

在以下 flex 搜索查询中创建AggregationDictionary时,我需要一些帮助

GET organisations/_search
{
"size": 0,
"aggs": {
"by_country": {
"nested": {
"path": "country"
},
"aggs": {
"by_country2": {
"filter": {
"bool": {
"must": [
{
"term": {
"country.isDisplayed": "true"
}
}
]
}
},
"aggs": {
"by_country3": {
"terms": {
"field": "country.displayName.keyword",
"size": 9999
}
}
}
}
}
}
}
}

我设法编写了这段可怕的代码,我敢肯定这是错误的,对此我是全新的。
AggregationDictionary aggs = new AggregationDictionary()
{
{
"countries_step1",
new NestedAggregation("countries_step1")
{
Path = "country",
Aggregations = new AggregationDictionary()
{
{
"countries_step2",
new FilterAggregation("countries_step2")
{
Filter = new BoolQuery
{
Must = new QueryContainer[] {
new NestedQuery
{
Query = new TermQuery
{
Field = "country.isDisplayed",
Value = true
}
}
}
},
Aggregations = new AggregationDictionary
{
{
"countries_step3",
new TermsAggregation("countries_step3")
{
Field = "country.displayName.keyword",
Size = 9999
}
}
}
}
}
}
}
}
};

有人可以告诉我方向是否正确吗?我正在使用Nest 6.6.0。有什么工具可以帮助您进行这些翻译?

最佳答案

到目前为止,您拥有的功能相当可靠,但是当您尝试通过以下调用执行此聚合时

var searchAsync = await client.SearchAsync<Document>(s => s.Size(0).Aggregations(aggs));

你会得到这个错误
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "query malformed, empty clause found at [14:22]"
}
],
"type" : "illegal_argument_exception",
"reason" : "query malformed, empty clause found at [14:22]"
},
"status" : 400
}

发送给elasticsearch的检查请求为我们提供了为什么发生的答案
{
"aggs": {
"countries_step1": {
"aggs": {
"countries_step2": {
"aggs": {
"countries_step3": {
"terms": {
"field": "country.displayName.keyword",
"size": 9999
}
}
},
"filter": {}
}
},
"nested": {
"path": "country"
}
}
},
"size": 0
}

filter子句为空,这是因为您尝试使用嵌套查询,但未传递 path parameter。我们这里不需要嵌套查询(如您的示例查询所示),我们可以将整个查询简化为
var aggs = new AggregationDictionary()
{
{
"countries_step1",
new NestedAggregation("countries_step1")
{
Path = "country",
Aggregations = new AggregationDictionary()
{
{
"countries_step2",
new FilterAggregation("countries_step2")
{
Filter = new BoolQuery
{
Must = new QueryContainer[]
{
new TermQuery
{
Field = "country.isDisplayed",
Value = true
}
}
},
Aggregations = new AggregationDictionary
{
{
"countries_step3",
new TermsAggregation("countries_step3")
{
Field = "country.displayName.keyword",
Size = 9999
}
}
}
}
}
}
}
}
};

现在我们有一个有效的请求发送到elasticsearch。

我们可以在以下方面做一些改进:

1.删除不必要的 bool(boolean) 查询
Filter = new BoolQuery
{
Must = new QueryContainer[]
{
new TermQuery
{
Field = "country.isDisplayed",
Value = true
}
}
},


Filter =
new TermQuery
{
Field = "country.isDisplayed",
Value = true
},

2.替换字符串字段名称

通常,当从.Net进行 call 时,有一种POCO类型可以帮助我们向Elasticsearch编写强类型的请求,从而帮助我们管理干净的代码和重构。这样,我们可以从
"country.displayName.keyword"


Infer.Field<Document>(f => f.Country.FirstOrDefault().DisplayName.Suffix("keyword"))

我的类型定义
public class Document
{
public int Id { get; set; }
[Nested]
public List<Country> Country { get; set; }
}

public class Country
{
public bool IsDisplayed { get; set; }
public string DisplayName { get; set; }
}

3.考虑使用流利的语法

使用NEST,您可以通过两种方式编写查询:使用对象初始化程序语法(您所做的)或借助流利的语法。 Have a look。尝试使用流利的语法编写以上查询,您将得到类似
var searchResponse = await client.SearchAsync<Document>(s => s
.Size(0)
.Aggregations(a => a.Nested("by_country", n => n
.Path(p => p.Country)
.Aggregations(aa => aa
.Filter("by_country2", f => f
.Filter(q => q
.Term(t => t
.Field(field => field.Country.FirstOrDefault().IsDisplayed)
.Value(true)))
.Aggregations(aaa => aaa
.Terms("by_country3", t => t
.Field(field => field.Country.FirstOrDefault().DisplayName.Suffix("keyword"))
.Size(9999)
)))))));

我发现它更容易阅读和编写,也许对您也会更好。

最后,请查看 docs并检查如何调试查询。

希望能有所帮助。

关于elasticsearch - 将ElasticSearch查询转换为Nest C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57976243/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com