ElasticSearch 过滤多个字段(带聚合)
ElasticSearch filtering on multiple fields (with aggregration)
我正在为网上商店构建一个分面过滤功能,如下所示:
Filter on Brand:
[ ] LG (10)
[ ] Apple (5)
[ ] HTC (3)
Filter on OS:
[ ] Android 4 (11)
[ ] Android 5 (2)
[ ] IOS (5)
我在 elasticsearch 中使用聚合和过滤,在学习了几天 ES(爱它!)后,这对我来说效果很好。但遗憾的是我现在卡在了实际的过滤上。
如果我点击 'LG',IOS 过滤器将被禁用并且 (5) 将变为 (0),右侧的结果将变为 13 [=29= 】 手机。太好了,到目前为止一切顺利。
现在,如果我点击 'Android 4',右侧只会显示 11 部手机。惊人的!到目前为止一切顺利:)
但是现在,如果我点击 'Android 5',所有结果都会消失。我不确定我做错了什么。我希望所有 Android 4 和 5 的 LG 手机都能出现。
下面是最后一个案例的示例查询。请注意,我用来构建分面过滤的查询中还包含一些其他字段。
{
"size":100,
"query":{
"filtered":{
"query":{
"match_all":[
]
},
"filter":{
"bool":{
"must":[
{
"term":{
"brand.untouched":"LG"
}
},
{
"term":{
"operating_system.untouched":"Android 4"
}
},
{
"term":{
"operating_system.untouched":"Android 5"
}
}
],
"should":[
],
"must_not":{
"missing":{
"field":"model"
}
}
}
},
"strategy":"query_first"
}
},
"aggs":{
"brand.untouched":{
"terms":{
"field":"brand.untouched"
}
},
"operating_system.untouched":{
"terms":{
"field":"operating_system.untouched"
}
},
"camera1":{
"histogram":{
"field":"camera1",
"interval":5,
"min_doc_count":0
}
},
"price_seperate":{
"histogram":{
"field":"price_seperate",
"interval":125,
"min_doc_count":0
}
}
}
}
有人知道解决办法吗?非常感谢。
您的查询正在搜索 operating_system.untouched
同时为 "Android 4" 和 "Android 5" 的文档,而这种情况永远不会发生,因此您得到零结果。您可以简单地使用 Terms Filter
,以便匹配 operating_system.untouched
的值为 "Android 4" 或 "Android 5" 的文档。以下是您应该使用的更新查询:
{
"size":100,
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"terms":{
"brand.untouched": [
"LG"
]
}
},
{
"terms":{
"operating_system.untouched": [
"Android 4",
"Android 5"
]
}
}
],
"must_not":{
"missing":{
"field":"model"
}
}
}
},
"strategy":"query_first"
}
},
"aggs":{
"brand.untouched":{
"terms":{
"field":"brand.untouched"
}
},
"operating_system.untouched":{
"terms":{
"field":"operating_system.untouched"
}
},
"camera1":{
"histogram":{
"field":"camera1",
"interval":5,
"min_doc_count":0
}
},
"price_seperate":{
"histogram":{
"field":"price_seperate",
"interval":125,
"min_doc_count":0
}
}
}
}
如果要添加另一组类别,如价格范围,只需在bool must
子句中添加一个bool should
子句即可。请参阅下面的示例,当您想要在两个范围 (0, 100]
和 (100, 200]
上筛选字段 price
时。这基本上意味着您可以嵌套 must
和 should
过滤器来实现您想要在 Elasticsearch 中实现过滤的任何布尔逻辑。
...
"must":[
{
"terms":{
"brand.untouched": [
"LG"
]
}
},
{
"terms":{
"operating_system.untouched": [
"Android 4",
"Android 5"
]
}
},
"bool": {
"should": [
{
"range": {
"price": {
"gt": 0,
"lte": 100
}
}
},
{
"range": {
"price": {
"gt": 100,
"lte": 200
}
}
}
]
}
],
...
我正在为网上商店构建一个分面过滤功能,如下所示:
Filter on Brand:
[ ] LG (10)
[ ] Apple (5)
[ ] HTC (3)
Filter on OS:
[ ] Android 4 (11)
[ ] Android 5 (2)
[ ] IOS (5)
我在 elasticsearch 中使用聚合和过滤,在学习了几天 ES(爱它!)后,这对我来说效果很好。但遗憾的是我现在卡在了实际的过滤上。
如果我点击 'LG',IOS 过滤器将被禁用并且 (5) 将变为 (0),右侧的结果将变为 13 [=29= 】 手机。太好了,到目前为止一切顺利。
现在,如果我点击 'Android 4',右侧只会显示 11 部手机。惊人的!到目前为止一切顺利:)
但是现在,如果我点击 'Android 5',所有结果都会消失。我不确定我做错了什么。我希望所有 Android 4 和 5 的 LG 手机都能出现。
下面是最后一个案例的示例查询。请注意,我用来构建分面过滤的查询中还包含一些其他字段。
{
"size":100,
"query":{
"filtered":{
"query":{
"match_all":[
]
},
"filter":{
"bool":{
"must":[
{
"term":{
"brand.untouched":"LG"
}
},
{
"term":{
"operating_system.untouched":"Android 4"
}
},
{
"term":{
"operating_system.untouched":"Android 5"
}
}
],
"should":[
],
"must_not":{
"missing":{
"field":"model"
}
}
}
},
"strategy":"query_first"
}
},
"aggs":{
"brand.untouched":{
"terms":{
"field":"brand.untouched"
}
},
"operating_system.untouched":{
"terms":{
"field":"operating_system.untouched"
}
},
"camera1":{
"histogram":{
"field":"camera1",
"interval":5,
"min_doc_count":0
}
},
"price_seperate":{
"histogram":{
"field":"price_seperate",
"interval":125,
"min_doc_count":0
}
}
}
}
有人知道解决办法吗?非常感谢。
您的查询正在搜索 operating_system.untouched
同时为 "Android 4" 和 "Android 5" 的文档,而这种情况永远不会发生,因此您得到零结果。您可以简单地使用 Terms Filter
,以便匹配 operating_system.untouched
的值为 "Android 4" 或 "Android 5" 的文档。以下是您应该使用的更新查询:
{
"size":100,
"query":{
"filtered":{
"filter":{
"bool":{
"must":[
{
"terms":{
"brand.untouched": [
"LG"
]
}
},
{
"terms":{
"operating_system.untouched": [
"Android 4",
"Android 5"
]
}
}
],
"must_not":{
"missing":{
"field":"model"
}
}
}
},
"strategy":"query_first"
}
},
"aggs":{
"brand.untouched":{
"terms":{
"field":"brand.untouched"
}
},
"operating_system.untouched":{
"terms":{
"field":"operating_system.untouched"
}
},
"camera1":{
"histogram":{
"field":"camera1",
"interval":5,
"min_doc_count":0
}
},
"price_seperate":{
"histogram":{
"field":"price_seperate",
"interval":125,
"min_doc_count":0
}
}
}
}
如果要添加另一组类别,如价格范围,只需在bool must
子句中添加一个bool should
子句即可。请参阅下面的示例,当您想要在两个范围 (0, 100]
和 (100, 200]
上筛选字段 price
时。这基本上意味着您可以嵌套 must
和 should
过滤器来实现您想要在 Elasticsearch 中实现过滤的任何布尔逻辑。
...
"must":[
{
"terms":{
"brand.untouched": [
"LG"
]
}
},
{
"terms":{
"operating_system.untouched": [
"Android 4",
"Android 5"
]
}
},
"bool": {
"should": [
{
"range": {
"price": {
"gt": 0,
"lte": 100
}
}
},
{
"range": {
"price": {
"gt": 100,
"lte": 200
}
}
}
]
}
],
...