Elasticsearch聚合每个groupId

时间:2015-12-08 13:09:28

标签: search elasticsearch count lucene aggregation

我在每个产品的弹性搜索中都有一个单独的文档。 每个产品都有唯一 productId 非唯一 groupId 以及其他属性,例如: categories < / em>的

我希望能够将不同的属性与每个唯一 groupId的计数进行汇总

示例:

doc 1:

{
  "productId": 123
  "groupId" xyz,
  "categories": [{"value": "shoes"}, {"value": "t-shirt"}]
}

doc 2:

{
  "productId": 345
  "groupId" xyz,
  "categories": [{"value": "shoes"}, {"value": "t-shirt"}]
}

doc 3:

{
  "productId": 456
  "groupId" abc,
  "categories": [{"value": "t-shirt"}]
}

doc 4:

{
  "productId": 567
  "groupId" abc,
  "categories": [{"value": "shoes"}, {"value": "makeup"}]
}

预期结果,如:

  • 鞋子:2
  • T恤:2
  • 化妆:1

所以如果每个项目存在同一个 groupId

,我希望计数一次

我的疑问:

{  
  "from":0,
  "size":0,
  "query":{  
     "filtered":{  
        "filter":{

        }
     }
  },
   "aggs": {
    "group": {
      "terms": {"field": "group"},
      "aggs": {
        "brand": {
            "terms": {"field": "productMeta.brand.value"}
        }
      }
    }
  }
}

回复:

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 25,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 3,
      "buckets": [
        {
          "key": "wlmr34210507",
          "doc_count": 8,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "generic",
                "doc_count": 8
              }
            ]
          }
        },
        {
          "key": "wlmr19524441",
          "doc_count": 4,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "maybelline",
                "doc_count": 4
              }
            ]
          }
        },
        {
          "key": "wlmr34121549",
          "doc_count": 2,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "maybelline",
                "doc_count": 2
              }
            ]
          }
        },
        {
          "key": "wlmr34317301",
          "doc_count": 2,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "dream on me",
                "doc_count": 2
              }
            ]
          }
        },
        {
          "key": "bbfs40549552",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "samsung",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "bobb7937347",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "chicco",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "wlmr24241413",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "maybelline",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "wlmr27504560",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "mr. beer",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "wlmr33986448",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "mr. beer",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "wlmr40806575",
          "doc_count": 1,
          "brand": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "healthtex",
                "doc_count": 1
              }
            ]
          }
        }
      ]
    }
  }
}

2 个答案:

答案 0 :(得分:1)

所以基本上我能够通过使用基数来解决这个问题,如下所示:

{  
      "from":0,
      "size":0,
      "query":{  
         "filtered":{  
            "filter":{  
            }
         }
      },
      "sort":{  
         "ts":{  
            "order":"desc",
            "mode":"max",
            "ignore_unmapped":true
         }
      },
      "aggs":{  
         "categories":{  
            "terms":{  
               "field":"productMeta.brand.value",
               "size":0
            },
            "aggs": {
                "category" : {
                    "cardinality" : {
                        "field" : "group"
                    }
                }
            }
         }
      }
   }

每个 productId

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 71,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "categories": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "chocolate",
          "doc_count": 23,
          "category": {
            "value": 23
          }
        },
        {
          "key": "notebook",
          "doc_count": 9,
          "category": {
            "value": 1
          }
        },
        {
          "key": "olive_oil",
          "doc_count": 7,
          "category": {
            "value": 7
          }
        },
        {
          "key": "physical_training",
          "doc_count": 5,
          "category": {
            "value": 5
          }
        },
        {
          "key": "ski",
          "doc_count": 5,
          "category": {
            "value": 2
          }
        },
        {
          "key": "gym_membership",
          "doc_count": 4,
          "category": {
            "value": 4
          }
        },
        {
          "key": "ski_boots",
          "doc_count": 4,
          "category": {
            "value": 1
          }
        },
        {
          "key": "vinegar",
          "doc_count": 4,
          "category": {
            "value": 4
          }
        },
        {
          "key": "bracelet",
          "doc_count": 3,
          "category": {
            "value": 3
          }
        },
        {
          "key": "handbags",
          "doc_count": 2,
          "category": {
            "value": 2
          }
        },
        {
          "key": "cider",
          "doc_count": 1,
          "category": {
            "value": 1
          }
        },
        {
          "key": "ice_cider",
          "doc_count": 1,
          "category": {
            "value": 1
          }
        },
        {
          "key": "jewelry_1",
          "doc_count": 1,
          "category": {
            "value": 1
          }
        },
        {
          "key": "laces",
          "doc_count": 1,
          "category": {
            "value": 1
          }
        },
        {
          "key": "stationery",
          "doc_count": 1,
          "category": {
            "value": 1
          }
        }
      ]
    }
  }
}

答案 1 :(得分:0)

使用嵌套的elasticsearch Terms Aggregations与您目前使用品牌的方式相同,您可以生成如下结构的输出:

 "aggregations": {
    "groups": {
      "buckets": [
        {
          "key": "xyz",
          "categories_per_group": {
            "buckets": [
              {
                "key": "shoes",
                "doc_count": 2
              },
              {
                "key": "t-shirt",
                "doc_count": 2
              }
            ]
          }
        },
        {
          "key": "abc",
          "categories_per_group": {
            "buckets": [
              {
                "key": "shoes",
                "doc_count": 1
              },
              {
                "key": "t-shirt",
                "doc_count": 1
              },
              {
                "key": "makeup",
                "doc_count": 1
              }
            ]
          }
        }
      ]
    }
  }

可能可以编写pipeline bucket script(ES 2.x)来收集群组存储区中不同类别的数量,如您所建议的那样。

但是,使用上面的聚合桶输出自己实现这种减少逻辑可能更简单,更快捷。