ElasticSearch - 嵌套过滤的聚合

时间:2017-08-22 15:26:51

标签: elasticsearch elasticsearch-5 elasticsearch-net

我正在寻找一种从已经过滤的2级嵌套对象中获取最小值和最大值的方法。所以下面我试图获得具有currencyCode英镑的最低和最高价格。每个产品可以有多个skus,每个sku可以有多个价格(虽然只有1个是GBP):

"hits": [
      {
        "_index": "product",
        "_type": "main",
        "_id": "1",
        "_score": 1,
        "_source": {         
          "skus": [
            {
              "prices": [
                {
                  "currencyCode": "GBP",
                  "price": 15
                }
              ]
            }
          ]
        }
      },{
        "_index": "product",
        "_type": "main",
        "_id": "2",
        "_score": 1,
        "_source": {         
          "skus": [
            {
              "prices": [
                {
                  "currencyCode": "GBP",
                  "price": 20
                }
              ]
            }
          ]
        }
      },
    {
        "_index": "product",
        "_type": "main",
        "_id": "3",
        "_score": 1,
        "_source": {         
          "skus": [
            {
              "prices": [
                {
                  "currencyCode": "GBP",
                  "price": 25
                }
              ]
            }
          ]
        }
      }]
  }

所以我想要15分钟,最高25分。我已经调查了Filter AggregationNested Aggregation,但无法得出答案。

我正在使用ElasticSearch 5.5版。

我想在转换为Nest .net。

之前先让查询正常工作

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您可以嵌套“嵌套”和“过滤”聚合,如下所示:

{
  "size": 0,
  "aggs": {
    "skus": {
      "nested": {
        "path": "skus"
      },
      "aggs": {
        "prices": {
          "nested": {
            "path": "skus.prices"
          },
          "aggs": {
            "gbp_filter": {
              "filter": {
                "term": {
                  "skus.prices.currencyCode": "GBP"
                }
              },
              "aggs": {
                "min_price": {
                  "min": {
                    "field": "skus.prices.price"
                  }
                },
                "max_price": {
                  "max": {
                    "field": "skus.prices.price"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

但是,既然你说只有一个价格可以是英镑,那么对于每个SKU,每种货币只能有一个价格吗?如果是这种情况,我建议不要在这里使用嵌套数据类型的价格。相反,你可以使用这样的映射:

{
  "product": {
    "properties": {
      "skus": {
        "type": "nested",
        "properties": {
          "prices": {
            "properties": {
              "GBP": {"properties": {"price": {"type": "integer"}}},
              "USD": {"properties": {"price": {"type": "integer"}}},
              ...remaining currencies...
            }
          }
        }
      }
    }
  }
}

映射不是很简洁,但查询效率会更高,查询也更好。 (几乎)任何时候你可以对你的数据进行非规范化以摆脱嵌套,即使你必须复制信息(为了满足不同类型的查询的需要),这是一个好主意。