如何从同一索引但从多种类型聚合ElasticSearch文档?

时间:2017-06-05 12:27:27

标签: java elasticsearch

假设我在该索引中有一个索引(产品索引)和多种类型(产品,sku,媒体等)。

示例文件:

在产品索引中,产品类​​型

{
  "_type": "product",
  "id": 1,
  "name" : "product 1"
}

{
  "_type": "product",
  "id": 2,
  "name" : "product 2"
}

在产品索引中,sku类型

{
  "_type": "sku",
  "id": 1,
  "name" : "sku 1",
  "product_id": 1
}
{
  "_type": "sku",
  "id": 2,
  "name" : "sku 2",
  "product_id": 1
}

{
  "_type": "sku",
  "id": 3,
  "name" : "sku 3",
  "product_id": 2
}

在产品索引中,媒体类型

{
  "_type": "media",
  "id": 1,
  "name" : "media 1",
  "product_id": 1
}

现在我想查询ElasticSearch以获取所有产品及其SKU,媒体。

预期回复:

[
 {
   "_type": "product",
   "id": 1,
   "name" : "product 1",
   "skus" : [
       {
         "_type": "sku",
         "id": 1,
         "name" : "sku 1",
         "product_id": 1
       },
       {
         "_type": "sku",
         "id": 2,
         "name" : "sku 2",
         "product_id": 1
       }
   ],
   media: [
     {
       "_type": "media",
       "id": 1,
       "name" : "media 1",
       "product_id": 1
     }
   ]
 },
 {
    "_type": "product",
    "id": 2,
    "name" : "product 2",
    "skus": [
        {
          "_type": "sku",
          "id": 3,
          "name" : "sku 3",
          "product_id": 2
        }
    ]       
 }
]

我正在审阅他们的所有文件https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html,但无法找到任何方法。

有关如何做的任何想法?

仅供参考,我正在使用java客户端与elasticsearch交谈。

1 个答案:

答案 0 :(得分:0)

_parent元字段用于映射功能以创建父/子关系。我为你实现了一个例子:

DELETE 44368941

PUT 44368941
{
  "mappings": {
    "product": {
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "keyword"}
      }
    },
    "sku": {
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "keyword"}
      },
      "_parent": { "type": "product" }
    },
    "media": {
      "properties": {
        "id": { "type": "integer" },
        "name": { "type": "keyword"}
      },
      "_parent": { "type": "product" }
    }
  }
}

POST 44368941/product/1
{
  "id": 1,
  "name" : "product 1"
}

POST 44368941/product/2
{
  "id": 2,
  "name" : "product 2"
}


POST 44368941/sku/1?parent=1
{
  "id": 1,
  "name" : "sku 1"
}

POST 44368941/sku/2?parent=1
{
  "id": 2,
  "name" : "sku 2"
}

POST 44368941/sku/3?parent=2
{
  "id": 3,
  "name" : "sku 3"
}

POST 44368941/media/1?parent=1
{
  "id": 1,
  "name" : "media 1"
}

POST 44368941/media/2?parent=1
{
  "id": 2,
  "name" : "media 2"
}


POST 44368941/product/_search
{
    "query" : {
        "bool": {
          "should": [
            {
              "has_child" : {
                  "type" : "sku",
                  "query" : {
                      "match_all": {}
                  },
                  "inner_hits" : {} 
              }
            },
            {
              "has_child" : {
                  "type" : "media",
                  "query" : {
                      "match_all": {}
                  },
                  "inner_hits" : {} 
              }
            }
          ]
        }
    }
}

结果如下。这与您的要求不一样,但非常相似。

{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 2,
    "hits": [
      {
        "_index": "44368941",
        "_type": "product",
        "_id": "1",
        "_score": 2,
        "_source": {
          "id": 1,
          "name": "product 1"
        },
        "inner_hits": {
          "media": {
            "hits": {
              "total": 2,
              "max_score": 1,
              "hits": [
                {
                  "_type": "media",
                  "_id": "1",
                  "_score": 1,
                  "_routing": "1",
                  "_parent": "1",
                  "_source": {
                    "id": 1,
                    "name": "media 1"
                  }
                },
                {
                  "_type": "media",
                  "_id": "2",
                  "_score": 1,
                  "_routing": "1",
                  "_parent": "1",
                  "_source": {
                    "id": 2,
                    "name": "media 2"
                  }
                }
              ]
            }
          },
          "sku": {
            "hits": {
              "total": 2,
              "max_score": 1,
              "hits": [
                {
                  "_type": "sku",
                  "_id": "1",
                  "_score": 1,
                  "_routing": "1",
                  "_parent": "1",
                  "_source": {
                    "id": 1,
                    "name": "sku 1"
                  }
                },
                {
                  "_type": "sku",
                  "_id": "2",
                  "_score": 1,
                  "_routing": "1",
                  "_parent": "1",
                  "_source": {
                    "id": 2,
                    "name": "sku 2"
                  }
                }
              ]
            }
          }
        }
      },
      {
        "_index": "44368941",
        "_type": "product",
        "_id": "2",
        "_score": 1,
        "_source": {
          "id": 2,
          "name": "product 2"
        },
        "inner_hits": {
          "media": {
            "hits": {
              "total": 0,
              "max_score": null,
              "hits": []
            }
          },
          "sku": {
            "hits": {
              "total": 1,
              "max_score": 1,
              "hits": [
                {
                  "_type": "sku",
                  "_id": "3",
                  "_score": 1,
                  "_routing": "2",
                  "_parent": "2",
                  "_source": {
                    "id": 3,
                    "name": "sku 3"
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

有关详细信息,请查看以下链接: