Elasticsearch具有子聚合的多选面构功能

时间:2015-05-25 12:36:35

标签: elasticsearch

鉴于以下数据:

curl -XPUT 'http://localhost:9200/products/'

curl -XPOST 'http://localhost:9200/products/product/_mapping' -d '{
    "product": {
        "_parent": {"type": "product_group"}
    }
}'

curl -XPUT 'http://localhost:9200/products/product_group/1' -d '{
  "title": "Product 1"
}'

curl -XPOST localhost:9200/products/product/1?parent=1 -d '{
    "height": 190, 
    "width": 120 
}'

curl -XPOST localhost:9200/products/product/2?parent=1 -d '{
    "height": 120, 
    "width": 100
}'

curl -XPOST localhost:9200/products/product/3?parent=1 -d '{
    "height": 110, 
    "width": 120
}'

产品上的子聚合会产生以下方面:

高度

  • 110(1)
  • 120(1)
  • 190(1)

宽度

  • 120(2)
  • 100(1)

如果我现在过滤 height 190 ,我想要的是从过滤器中排除高度聚合,结果将是:

高度

  • 110(1)
  • 120(1)
  • 190(1)

宽度

  • 120(1)

这可以通过过滤器聚合来解决,但我不确定它是否有效或者在使用父子关系时语法是什么。

请参阅http://distinctplace.com/2014/07/29/build-zappos-like-products-facets-with-elasticsearch/

到目前为止我尝试过:

curl -XGET 'http://localhost:9200/products/product_group/_search?pretty=true' -d '{
    "filter": {
        "has_child": {
            "type": "product",
            "filter": {
                "term": {"height": 190}
            },
            "inner_hits": {} 
        }
    },
    "aggs": {
        "to-products": {
            "children": {"type": "product"},
            "aggs": {
                "height": {
                    "filter": {"match_all": {}},
                    "aggs": {
                        "height": {
                            "terms": {"field": "height", "size": 10}
                        }
                    }
                },
                "width": {
                    "filter": {
                        "and": [{"terms": { "height": [190]}}]
                    },
                    "aggs": {
                        "width": {
                            "terms": {"field": "width", "size": 10}
                        }
                    }
                }
            }  
        }
    }
}
'

1 个答案:

答案 0 :(得分:1)

我不完全理解您的问题,但如果您希望在子聚合中进行多个聚合,则必须在聚合中的每个字段之前附加父类型名称。

这里是修改后的查询,

 curl -XPOST "http://localhost:9200/products/product_group/_search?pretty=true" -d'
    {
   "size": 0,
   "filter": {
      "has_child": {
         "type": "product",
         "filter": {
            "term": {
               "product.height": 190
            }
         },
         "inner_hits": {}
      }
   },
   "aggs": {
      "to-products": {
         "children": {
            "type": "product"
         },
         "aggs": {
            "height": {
               "filter": {
                  "match_all": {}
               },
               "aggs": {
                  "height": {
                     "terms": {
                        "field": "product.height",
                        "size": 10
                     }
                  }
               }
            },
            "width": {
               "filter": {
                  "and": [
                     {
                        "terms": {
                           "product.height": [
                              190
                           ]
                        }
                     }
                  ]
               },
               "aggs": {
                  "width": {
                     "terms": {
                        "field": "product.width",
                        "size": 10
                     }
                  }
               }
            }
         }
      }
   }
}'

在文档的任何地方都没有提到,这让许多用户感到困惑,我猜他们认为子聚合与嵌套聚合一样,因此聚合方式相同。