排序和过滤弹性搜索的热门文章文档

时间:2019-03-15 13:50:39

标签: elasticsearch elasticsearch-aggregation

让我说我对这样的文档有一个简单的产品索引:

{
   "product_name": "some_product",
   "category": "some_cotegory",
   "price": "200"
   "sold_times": "5",
   "store": "store1"
}

,我想获得其类别和每家商店中最昂贵的产品,这些产品的销售量少于3次,我希望按商店,类别和价格进行订购。

我可以使用两个术语聚合和热门搜索聚合来获得每个商店中其类别中最昂贵的产品,但是如何对这些热门搜索结果进行排序和过滤?我确实需要在执行热门点击agg之后过滤结果,因此过滤查询不是解决方案。我怎样才能做到这一点?谢谢

编辑:

长话短说-我需要SQL的弹性等效项:

SELECT p.* 
FROM products AS p
INNER JOIN (
    SELECT max(price) AS price, categroy, store 
    FROM products
    GROUP BY category, store
) AS max_prices ON p.price = max_prices.price AND p.category = max_prices.category AND p.store = max_prices.store
WHERE p.sold_times < 3;

2 个答案:

答案 0 :(得分:0)

您可以过滤搜索,以仅退回售出少于3次的产品,然后按商店和类别汇总这些产品,最后应用热门匹配汇总来获得该类别(该商店)中最昂贵的商品。像

{
  "size": 0,
  "query": {
    "range": {
      "sold_times": {
        "lt": 3
      }
    }
  },
  "aggs": {
    "store": {
      "terms": {
        "field": "store",
        "size": 10
      },
      "aggs": {
        "category": {
          "terms": {
            "field": "category",
            "size": 10
          },
          "aggs": {
            "most_expensive": {
              "top_hits": {
                "size": 1,
                "sort": [
                  {
                    "price": {
                      "order": "desc"
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

好吧,经过一番搜索,我找到了“可能的”解决方案。我可以将Bucket Selector聚合与一些脚本结合使用,这些脚本可以访问热门匹配属性进行过滤,并可以使用Bucket Sort聚合进行类似的排序方法(可以在此处找到一些信息:How do I filter top_hits metric aggregation result [Elasticsearch]

但是我面临着聚合的另一个问题。因为我想使用很多类别(例如在通用搜索查询中使用的“滚动”或“大小和来源”),但是使用聚合无法轻松完成。有一个Composite Aggregation可以做类似的事情,但毕竟查询是如此复杂,以至于让我非常害怕,所以我决定放弃它,并在弹性之外进行分组。

可悲的是,没有一种简单的方法可以在Elastic中进行这样的常见分析查询。