json - 对多个字段进行ElasticSearch过滤(聚合)

标签 json elasticsearch facet nosql

我正在为网上商店构建多面过滤功能,如下所示:

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个Android手机。很好,到目前为止很好。

现在,如果我单击“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 should子句中添加bool must子句。要在两个区域price(0, 100]上对字段(100, 200]进行过滤时,请参见以下示例。这基本上意味着您可以嵌套mustshould过滤器,以实现要在Elasticsearch中实现过滤的任何 bool(boolean) 逻辑。
... 
"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
                    }
                }
            }
        ]
    }
],
...

关于json - 对多个字段进行ElasticSearch过滤(聚合),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30007439/

相关文章:

Php Json 获取多个对象

php - MySQL 使用 AJAX 和 JSON 删除行失败

elasticsearch - elasticsearch将 “and filter”与 “bool filter”混合

elasticsearch - 尽管知道电子邮件确实存在,但是电子邮件的ES curl无法返回正确的结果

r - 使用 sjplot 的 plot_model 函数时调整刻面顺序和图例标签

android - 使用改造和 Moshi 解析 api 响应不完全 "json"

json - 获取xsuperobject将未命名的数组解析为tobject结构

elasticsearch - elasticsearch _search api stats标签有什么作用?

r - 调整 facet_grid 中 One Line 的线型

r - 如何使用facet和margin = TRUE更改ggplot中的strip.text标签