【问题标题】:ElasticSearch 1x - aggregate on object conditionsElasticSearch 1x - 聚合对象条件
【发布时间】:2016-06-21 15:54:11
【问题描述】:

我想聚合具有内部对象的数据。例如:

{
    "_index": "product_index-en",
    "_type": "elasticproductmodel",
    "_id": "000001111",
    "_score": 6.3316255,
    "_source": {
        "productId": "11111111111",
        "productIdOnlyLetterAndDigit": "11111111111",
        "productIdOnlyDigit": "11111111111",
        "productNumber": "11111111111",
        "name": "Glow Plug",
        "nameOnlyLetterAndDigit": "glowplug",
        "productImageLarge": "11111111111.jpg",
        "itemGroupId": "11111",
        "relatedProductIds": [],
        "dataAreaCountries": [
            "fra",
            "pol",
            "uk",
            "sie",
            "sve",
            "atl",
            "ita",
            "hol",
            "dk"
        ],
        "oemItems": [
            {
                "manufactorName": "BERU",
                "manufacType": "0"
            },
            {
                "manufactorName": "LUCAS",
                "manufacType": "0"
            }
        ]
    }
}

我需要能够聚合 oemItems.manufactorName 值,但仅限于 oemItems.manufacType 为“0”的情况。我尝试了许多示例,例如此处接受的示例(Elastic Search Aggregate into buckets on conditions),但我似乎无法理解它。

我尝试过关注,希望它会首先在 manufacType 上进行聚合,它确实如此,然后是每种类型的 manufactorName,它似乎显示正确的命中计数。但是,manufactorName 的存储桶是空的:

GET /product_index-en/_search
{
"size": 0, 
  "aggs": {
    "baked_goods": {
      "nested": {
        "path": "oemItems"
      },
      "aggs": {
        "test1": {
          "terms": {
            "field": "oemItems.manufacType",
            "size": 500
          },
          "aggs": {
            "test2": {
              "terms": {
                "field": "oemItems.manufactorName",
                "size": 500
              }
            }
          }
        }
      }
    }
  }
}

结果:

{
   "took": 27,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 471214,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "baked_goods": {
         "doc_count": 677246,
         "test1": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
               {
                  "key": "0",
                  "doc_count": 436557,
                  "test2": {
                     "doc_count_error_upper_bound": 0,
                     "sum_other_doc_count": 0,
                     "buckets": []
                  }
               },
               {
                  "key": "1",
                  "doc_count": 240689,
                  "test2": {
                     "doc_count_error_upper_bound": 0,
                     "sum_other_doc_count": 0,
                     "buckets": []
                  }
               }
            ]
         }
      }
   }
}

我还尝试添加一个嵌套术语过滤器,仅查看具有以下查询的 manufacType 1 的 oemItems。但是,它会返回 oemItems 包含 manufacType 1 的对象,这意味着产品中的 oemItems 仍然包含 1 或 0 manufacType。我不明白如何对此响应进行聚合只会返回 oemItems.manufactorName ,其中 oemItems.manufacType 为 0

GET /product_index-en/_search 
{
        "query" : { "match_all" : {} },
        "filter" : {
            "nested" : {
                "path" : "oemItems",
                "filter" : {
                    "bool" : {
                        "must" : [
                            {
                                "term" : {"oemItems.manufacType" : "1"}
                            }
                        ]
                    }
                }
            }
        }    
}

【问题讨论】:

  • 首先,您需要确保oemItems 在您的映射中属于nested 类型。是这样吗?
  • @Val 不,它不是嵌套类型。我会改变它,看看是否有帮助。
  • @Val 我已将其设置为嵌套并在我的帖子中添加了一个示例。
  • 如果您只需要 manufacType = 0 所在的名称,则应添加 nested term 过滤器,然后您只能为 manufactorName 字段提供单个术语聚合。试试看。
  • @Val 你有例子吗?

标签: elasticsearch nest


【解决方案1】:

到目前为止的良好开端。试试这样吧:

POST /product_index-en/_search
{
  "size": 0,  
  "query": {
     "nested": {
        "path": "oemItems",
        "query": {
           "term": {
              "oemItems.manufacType": "0"
           }
        }
     }
  },
  "aggs": {
    "baked_goods": {
      "nested": {
        "path": "oemItems"
      },
      "aggs": {
        "test1": {
          "terms": {
            "field": "oemItems.manufactorName",
            "size": 500
          }
        }
      }
    }
  }
}

【讨论】:

  • 问题是 Object.oemItems 可以包含具有 manufacType 1、0 或其中多个的对象。因此,查询返回的命中将包括除了 0 之外还具有 manufactorType 1 的对象,当我对这些结果进行聚合时,我最终得到 manufacType 1 和 0。我想我需要在聚合中添加一个过滤器,所以它只返回 manufacType 0 的 oemItems?
  • 试试吧,它应该可以工作,因为嵌套字段是下面的不同文档。
  • 感谢您的帮助 Val。我做到了,但是 test1 中的存储桶是空的
  • 啊!显然,我必须在 manufactorName 上使用“确切”后缀。 Bucket 现在返回物品 - 处理其他人写的东西真是太棒了!非常感谢瓦尔。我现在将进行大量测试以确保结果正确,如果是,我将接受您的回答。祝你有美好的一天!
  • 太棒了,很高兴你知道了!
猜你喜欢
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 2017-09-24
  • 2021-05-14
相关资源
最近更新 更多