Elasticsearch组和按嵌套字段的最小值排序

时间:2017-09-04 15:21:50

标签: sorting elasticsearch nested aggregation

我有不同商店的产品结构,价格不同:

[{
  "name": "SomeProduct",
  "store_prices": [
    {
      "store": "FooStore1",
      "price": 123.45
    },
    {
      "store": "FooStore2",
      "price": 345.67
    }
  ]
},{
  "name": "OtherProduct",
  "store_prices": [
    {
      "store": "FooStore1",
      "price": 456.78
    },
    {
      "store": "FooStore2",
      "price": 234.56
    }
  ]
}]

我想显示一个产品清单,以最低价格升序排序,限制为10个结果,这样:

  • SomeProduct:123.45 USD
  • 其他产品:234.56美元

怎么做?我已经尝试了https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html中描述的嵌套聚合方法,但它只返回所有产品的最低价格,而不是每个产品的相应最低价格:

{
  "_source": [
    "name",
    "store_prices.price"
  ],
  "query": {
    "match_all": {}
  },
  "sort": {
    "store_prices.price": "asc"
  },
  "aggs": {
    "stores": {
      "nested": {
        "path": "store_prices"
      },
      "aggs": {
        "min_price": {"min": {"field": "store_prices.price"}}
      }
    }
  },
  "from": 0,
  "size": 10
}

在SQL中,我可以使用以下查询来描述我想要做的事情。我害怕我在思考太多"在sql":

SELECT
  p.name,
  MIN(s.price) AS price
FROM
  products p
INNER JOIN
  store_prices s ON s.product_id = p.id
GROUP BY
  p.id
ORDER BY
  price ASC
LIMIT 10

1 个答案:

答案 0 :(得分:1)

您需要nested sorting

{
   "query": // HERE YOUR QUERY,
   "sort": {
     "store_prices.price": {
       "order" : "asc",
       "nested_path" : "store_prices",
       "nested_filter": {
          // HERE THE FILTERS WHICH ARE EVENTUALLY 
          // FILTERING OUT SOME OF YOUR STORES
       }
     }
   }
}

注意您必须在嵌套过滤器字段中重复最终的嵌套查询。然后,您会在响应的score字段中找到价格。