【问题标题】:Kibana DSL, aggregate on field where field has multiple valuesKibana DSL,在字段具有多个值的字段上聚合
【发布时间】:2021-05-11 18:46:43
【问题描述】:

例如我有这样的数据:

{"product": "ProductA", "region": "Region 1", "sales": 25000}
{"product": "ProductA", "region": "Region 2", "sales": 30000}
{"product": "ProductA", "region": "Region 3", "sales": 45000}
{"product": "ProductB", "region": "Region 1", "sales": 25000}
{"product": "ProductB", "region": "Region 3", "sales": 30000}
{"product": "ProductB", "region": "Region 3", "sales": 45000}

我想获得productRegion 1Region 2 中的所有产品。 所以它应该只返回ProductA

我试过了,但没用

GET /_search
{
  "aggs": {
    "metrics": {
      "terms":{
        "field": "product"
      }
    }
  },
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "should": [
        { "term" : { "region" : "Region 1" } },
        { "term" : { "region" : "Region 2" } }
      ]
    }
  }
}

【问题讨论】:

    标签: elasticsearch kibana


    【解决方案1】:

    尝试布尔查询,您的查询可能如下所示

    GET /saga/_search
    {
      "query": {"bool": {"must": [
        {"term": {
          "product": {
            "value": "ProductA"
          }
        }},
        {"term": {
          "region": {
            "value": "Region 1"
          }
        }}
      ]
      }
      }
    }

    还有卷曲形式

    curl -XGET "http://XXXXX/xxx/_search" -H 'Content-Type: application/json' -d'{  "query": {"bool": {"must": [    {"term": {      "product": {        "value": "ProductA"      }    }},    {"term": {      "region": {        "value": "Region 1"      }    }}  ]  }  }}'
    

    【讨论】:

    • 但是如果我想找到所有符合特定规则的产品怎么办?
    • 这个查询基本上匹配所有具有 ProductARegion 1 的文档,但我认为 @RnD 想要一个您拥有的所有产品名称的列表至少一个具有该产品名称 + Region 1 的文档和一个具有该产品名称 + Region 2 的文档
    【解决方案2】:

    我不确定您是否会为此找到纯 ES 解决方案。

    在您的情况下,如果可能,我会重新考虑数据的结构 - 我更喜欢以下内容:

    {
      "product": "ProductA", 
      "regions": [
        {
          "name": "Region 1", 
          "sales": 25000
        },
        {
          "name": "Region 2", 
          "sales": 30000
        },
        {
          "name": "Region 3", 
          "sales": 45000
        }
      ]
    }
    
    {
      "product": "ProductB", 
      "regions": [
        {
          "name": "Region 1", 
          "sales": 25000
        },
        {
          "name": "Region 3", 
          "sales": 45000
        }
      ]
    }
    

    这样可以更轻松地搜索您想要的内容。

    编辑:为我建议的数据结构添加了示例查询(未经测试,但应该可以)

    GET /_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "nested": {
                "path": "regions",
                "query": {
                  "bool": {
                    "filter": [
                      {
                        "term": {
                          "regions.name": "Region 1"
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "nested": {
                "path": "regions",
                "query": {
                  "bool": {
                    "filter": [
                      {
                        "term": {
                          "regions.name": "Region 2"
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      您可以尝试min_doc_count 受术语聚合支持

       GET products/_search
      {
        "size": 0,
        "query": {
          "bool": {
            "should": [
              {
                "terms": {
                  "region.keyword": [
                    "Region 1",
                    "Region 2"
                  ]
                }
              }
            ]
          }
        },
        "aggs": {
          "metrics": {
            "terms": {
              "field": "product.keyword",
              "size": 10,
              "min_doc_count": 2 // <====== this should match with count of regions mentioned in the query part
            }
          }
        }
      }
      

      【讨论】:

      • 抱歉,我不太明白,你的意思是我应该用must 替换should 吗?如果是这样,那么遗憾的是它没有用。
      • 您指出的事实是,此查询匹配区域 1 或区域 2 中的所有产品。但使用 mustfilter i> 不能解决问题,因为每个产品的不同区域不在同一个文档中。
      • 我的错...我更新了我的答案..请立即尝试。
      • @Sahil Gupta,现在说得通了。鉴于限制条件,即文档中 region 和 _product _ 的组合是唯一的,这非常有效。我喜欢。但是,如果我们有(如问题示例中的 - 虽然我不确定它是否是故意的),Product B 两次使用Region 3,这给我们带来了一些麻烦。使用该查询搜索 Region 3Region 4 将返回 Product B,因为它有两个与 Region 3 匹配的文档。
      猜你喜欢
      • 2019-09-01
      • 2022-11-30
      • 2018-06-16
      • 2020-12-08
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      相关资源
      最近更新 更多