【问题标题】:Elasticsearch aggregate by multiple fields separatelyElasticsearch 按多个字段分别聚合
【发布时间】:2016-07-06 11:41:20
【问题描述】:

我有一个包含 2 个字段和一些文档的索引,如下所示:

city                team
=========================================
New York            New York Knicks
New York            Brooklyn Nets
New Orleans         New Orleans Pelicans

我的目标是提供一个在这两个字段上进行搜索的自动完成功能,如下所示:

Query: [ new                  ]
       +----------------------+
       |     Cities           |
       +----------------------+
       | New York             |
       | New Orleans          |
       +----------------------|
       |     Teams            |
       +----------------------|
       | New York Knicks      |
       | New Orleans Pelicans |
       +----------------------+

我过滤文档的查询非常简单:

"query": {
    "bool": {
        "should": [
            {
                "match_phrase_prefix": {
                    "city": "new"
                }
            },
            {
                "match_phrase_prefix": {
                    "team": "new"
                }
            }
        ]
    }
}

但是,我遇到了聚合问题。我的第一个方法是:

"aggs": {
    "city": {
        "terms": {
            "field": "city.raw"
        }
    },
    "team": {
        "terms": {
            "field": "team.raw"
        }
    }
}

raw 是用于聚合目的的 not_analyzed 字段副本)

这不起作用,因为Brooklyn Nets 包含在结果中 - 它不应该:

"aggregations": {
    "city": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
            {
                "key": "New York",
                "doc_count": 2
            },
            {
                "key": "New Orleans",
                "doc_count": 1
            }
        ]
    },
    "team": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
            {
                "key": "Brooklyn Nets",
                "doc_count": 1
            },
            {
                "key": "New Orleans Pelicans",
                "doc_count": 1
            },
            {
                "key": "New York Knicks",
                "doc_count": 1
            }
        ]
    }
}

我不知道如何使用单个请求使其工作。 这个例子只是说明性的,在实际场景中我有更多的字段和文档要搜索和聚合,所以向服务器发出多个请求不是一个好主意,特别是因为自动完成系统应该尽可能快。

任何帮助将不胜感激。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您需要一个过滤器聚合来根据查询本身中的过滤器过滤要聚合的文档:

      "aggs": {
        "city": {
          "filter": {
            "bool": {
              "must": [
                {
                  "query": {
                    "match_phrase_prefix": {
                      "city": "new"
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "cities": {
              "terms": {
                "field": "city.raw"
              }
            }
          }
        },
        "team": {
          "filter": {
            "bool": {
              "must": [
                {
                  "query": {
                    "match_phrase_prefix": {
                      "team": "new"
                    }
                  }
                }
              ]
            }
          },
          "aggs": {
            "cities": {
              "terms": {
                "field": "team.raw"
              }
            }
          }
        }
      }
    

    【讨论】:

      【解决方案2】:

      您的查询,

      "query": {
          "bool": {
              "should": [
                  {
                      "match_phrase_prefix": {
                          "city": "new"
                      }
                  },
                  {
                      "match_phrase_prefix": {
                          "team": "new"
                      }
                  }
              ]
          }
      }
      

      在结果中返回带有“City:New York Team:Brooklyn Nets”的文档。因为“city”字段有前缀“new”,而“team”字段没有。

      我认为,当您使用聚合时,“City:New York Team:Brooklyn Nets”的文档会被计算在内。由于“City:New York”,“Team:Brooklyn Nets”文档包含在查询的结果集中,并被计入存储桶中。

      如果要检查,请将 minimum_should_match 设置为 2。

      【讨论】:

      • 还是谢谢你的回答,但这对我没有帮助。
      猜你喜欢
      • 2020-02-18
      • 1970-01-01
      • 2015-07-12
      • 2016-11-23
      • 1970-01-01
      • 2018-10-18
      • 2013-08-29
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多