将 ElasticSearch 查询转换为 Nest c#
Translate ElasticSearch query to Nest c#
我需要一些帮助来根据以下 elasticsearch 查询创建 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.删除不必要的布尔查询
Filter = new BoolQuery
{
Must = new QueryContainer[]
{
new TermQuery
{
Field = "country.isDisplayed",
Value = true
}
}
},
至
Filter =
new TermQuery
{
Field = "country.isDisplayed",
Value = true
},
2。替换字符串字段名称
通常,当从 .Net 进行调用时,有某种 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 查询创建 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.删除不必要的布尔查询
Filter = new BoolQuery
{
Must = new QueryContainer[]
{
new TermQuery
{
Field = "country.isDisplayed",
Value = true
}
}
},
至
Filter =
new TermQuery
{
Field = "country.isDisplayed",
Value = true
},
2。替换字符串字段名称
通常,当从 .Net 进行调用时,有某种 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 并检查如何调试查询。
希望对您有所帮助。