![](/img/trans.png)
[英]using NEST (or another client) to run query on authenticated ES server
[英]Applying Term, Filter and Aggregation in one Es Query using Nest
我正在使用 ElasticSearch 的 Nest 7.17.x 尝试在单个查询中应用术语、过滤器和聚合。
Term 是一个文档 id 限制,它应该限制所有后续过滤器和聚合。 过滤器是将价格限制在特定范围内。 聚合到是制作价格桶。
在下面的示例中,看起来价格过滤器和期限限制都没有被应用,因为我返回的文档的 id 超出限制并且价格大于过滤器。
var orderChangedArgFilter = client.Search<Product>(s => s
.Query(q => +q.Terms(p => p.Field("id").Terms(productIds)))
.Aggregations(aggs => aggs
.Filter("user filter with aggs", f => f
.Filter(q => q.Range(rf => rf.Field("price").GreaterThanOrEquals(0.01).LessThan(50.0)))
.Aggregations(childAggs => childAggs
.Range("0 to 50 price agg", r => r.Field("price").Ranges(rs => rs.From(0.0).To(50.0)))
.Range("50 to 100 price agg", r => r.Field("price").Ranges(rs => rs.From(50.0).To(100.0)))
.Range("100 to 150 price agg", r => r.Field("price").Ranges(rs => rs.From(100.0).To(150.0)))
)
)
)
);
如何更正查询以先应用期限限制,然后再应用过滤器?
编辑1:
看起来文档 ID 术语限制按预期工作,但过滤器没有。
我的引擎是通过 AppSearch 创建的。 看起来价格字段的数据类型实际上是文本而不是数字(在抽象的弹性引擎上),即使我已经在 AppSearch 引擎上指定了数字。 这似乎是问题的原因。
原始索引映射
{
".ent-search-engine-documents-luke-test": {
"mappings": {
"dynamic": "true",
"properties": {
"price": {
"fields": {
"prefix": {
"search_analyzer": "q_prefix",
"type": "text",
"analyzer": "i_prefix",
"index_options": "docs"
},
"enum": {
"ignore_above": 2048,
"type": "keyword"
},
"float": {
"ignore_malformed": true,
"type": "double"
},
"joined": {
"search_analyzer": "q_text_bigram",
"type": "text",
"analyzer": "i_text_bigram",
"index_options": "freqs"
},
"stem": {
"type": "text",
"analyzer": "iq_text_stem"
},
"delimiter": {
"type": "text",
"analyzer": "iq_text_delimiter",
"index_options": "freqs"
},
"location": {
"ignore_malformed": true,
"type": "geo_point",
"ignore_z_value": false
},
"date": {
"ignore_malformed": true,
"type": "date",
"format": "strict_date_time||strict_date"
}
},
"type": "text",
"analyzer": "iq_text_base",
"index_options": "freqs"
},
"id": {
"type": "keyword"
},
"title": {
"fields": {
"prefix": {
"search_analyzer": "q_prefix",
"type": "text",
"analyzer": "i_prefix",
"index_options": "docs"
},
"enum": {
"ignore_above": 2048,
"type": "keyword"
},
"float": {
"ignore_malformed": true,
"type": "double"
},
"joined": {
"search_analyzer": "q_text_bigram",
"type": "text",
"analyzer": "i_text_bigram",
"index_options": "freqs"
},
"stem": {
"type": "text",
"analyzer": "iq_text_stem"
},
"delimiter": {
"type": "text",
"analyzer": "iq_text_delimiter",
"index_options": "freqs"
},
"location": {
"ignore_malformed": true,
"type": "geo_point",
"ignore_z_value": false
},
"date": {
"ignore_malformed": true,
"type": "date",
"format": "strict_date_time||strict_date"
}
},
"type": "text",
"analyzer": "iq_text_base",
"index_options": "freqs"
}
},
"dynamic_templates": [
{
"permissions": {
"mapping": {
"type": "keyword"
},
"match": "_*_permissions"
}
},
{
"thumbnails": {
"mapping": {
"type": "binary"
},
"match": "_thumbnail_*"
}
},
{
"data": {
"match_mapping_type": "*",
"mapping": {
"fields": {
"enum": {
"ignore_above": 2048,
"type": "keyword"
},
"float": {
"ignore_malformed": true,
"type": "double"
},
"delimiter": {
"type": "text",
"index_options": "freqs",
"analyzer": "iq_text_delimiter"
},
"joined": {
"search_analyzer": "q_text_bigram",
"type": "text",
"index_options": "freqs",
"analyzer": "i_text_bigram"
},
"prefix": {
"search_analyzer": "q_prefix",
"type": "text",
"index_options": "docs",
"analyzer": "i_prefix"
},
"location": {
"ignore_malformed": true,
"type": "geo_point",
"ignore_z_value": false
},
"date": {
"ignore_malformed": true,
"type": "date",
"format": "strict_date_time||strict_date"
},
"stem": {
"type": "text",
"analyzer": "iq_text_stem"
}
},
"type": "text",
"index_options": "freqs",
"analyzer": "iq_text_base"
}
}
}
]
}
}
}
是否仍然可以针对通过 AppSearch 创建的引擎使用 Nest 客户端?
我的查询有几个问题。 首先,我应该使用字段名称price.float
,它是 ES 与 AppSearch 上price
字段的数字表示。 您可以从 AppSearch 提供的Explain
端点中弄清楚这一点。
下一个问题是我的查询结构,我不应该使用FilteredAggregation
。 我的意图是不将过滤器专门应用于聚合,而是应用于查询结果。
最后,从Aggregations
中检索结果并不是那么简单。 将内容转储到控制台错误地显示了一个空聚合,但是在通过.EnableDebugMode()
header 调查调试信息后,我能够看到我确实收到了结果。 应用断点并检查 object 的结果使我能够检索到我想要的 object。
var orderChangedArgFilter = client.Search<Product>(s => s
.Query(q => +q.Range(rf => rf.Field("price.float").GreaterThanOrEquals(0.01).LessThan(50.0)) && +q.Terms(p => p.Field("id").Terms(productIds)))
.Aggregations(a => a
.Range("Price aggs", r => r
.Field("price.float")
.Ranges(rs =>
rs.From(0.01).To(50.0).Key("0 to 50 price agg"),
rs => rs.From(50.01).To(100).Key("50 to 100 price agg"),
rs => rs.From(100.01).Key("From 100 price agg")))
)
);
orderChangedArgFilter.Aggregations.Dump();
// vs
var agg = (Nest.BucketAggregate)orderChangedArgFilter.Aggregations.GetValueOrDefault("Price aggs");
var buckets = agg.Items.Select(b => (RangeBucket)b).ToList();
Console.WriteLine(buckets[0].Key + ", " + buckets[0].DocCount);
请注意以下屏幕截图底部的文本行,其中显示了Key
和DocCount
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.