嵌套查询中数组的聚合

时间:2016-01-16 02:14:48

标签: elasticsearch aggregation nested-queries

我正在尝试查询与特定用户至少有一种颜色的所有用户,但我能够做到这一点但是我无法弄清楚如何aggregate我的结果让我可以让用户获得他们共同的颜色。

示例用户的部分文档如下:

{
    // ... other fields
    "colors" : [
        {
            "id" : 1,
            "name" : "Green"
        },
        {
            "id" : 7,
            "name" : "Blue"
        }
    ]
}

这是我的查询,以获取与另一个具有红色,橙色和绿色的用户共同的颜色:

{
  "query": {
    "nested": {
      "path": "colors",
      "scoreMode": "sum",
      "query": {
        "function_score": {
          "filter": {
            "terms": {
              "colors.name": [
                "Red","Orange","Green"
              ]
            }
          },
          "functions": [
            // Functions here for custom scoring
          ]
        }
      }
    }
  }
}

如何聚合用户与常用颜色?

2 个答案:

答案 0 :(得分:1)

您需要使用nested aggregation,然后将filter aggregation应用于颜色,最后使用top hits来获取匹配的颜色。我使用source filtering来获取颜色值

这是查询

{
  "size": 0,
  "query": {
    "nested": {
      "path": "colors",
      "query": {
        "terms": {
          "colors.color": [
            "green",
            "red"
          ]
        }
      }
    }
  },
  "aggs": {
    "user": {
      "terms": {            <----get users with unique name or user_id
        "field": "name",
        "size": 10
      },
      "aggs": {
        "nested_color_path": {  <---go inside nested documents
          "nested": {
            "path": "colors"
          },
          "aggs": {
            "match_color": {
              "filter": {         <--- use the filter to match for colors
                "terms": {
                  "colors.color": [
                    "green",
                    "red"
                  ]
                }
              },
              "aggs": {
                "get_match_color": {  <--- use this to get matched color
                  "top_hits": {
                    "size": 10,
                     "_source": {
                       "include": "name"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

您必须使用nested aggregations来实现此目的。请参阅以下查询:

POST <index>/<type>/_search
{
   "query": {
      "nested": {
         "path": "colors",
         "query": {
            "terms": {
               "colors.name": [
                  "Red",
                  "Orange",
                  "Green"
               ]
            }
         }
      }
   },
   "aggs": {
      "users_with_common_colors": {
         "terms": {
            "field": "user_id",
            "size": 0,
            "order": {
                "color_distribution>common": "desc"  <-- This will sort the users in descending order of number of common colors
            }
         },
         "aggs": {
            "color_distribution": {
               "nested": {
                  "path": "colors"
               },
               "aggs": {
                  "common": {
                     "filter": {
                        "terms": {
                           "colors.name": [
                              "Red",
                              "Orange",
                              "Green"
                           ]
                        }
                     },
                     "aggs": {
                        "colors": {
                           "terms": {
                              "field": "colors.name",
                              "size": 0
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}