在兄弟姐妹

时间:2017-12-16 17:56:22

标签: elasticsearch

不太确定如何形成这个问题,所以我将跳到一个例子中。假设我有以下文件:

{
    elements: [
        {name: 'foo'},
        {name: 'bar'},
        {name: 'baz'}
    ]
},
{
    elements: [
        {name: 'foo'},
        {name: 'baz'}
    ]  
}

elements包含嵌套文档的位置。我希望能够聚合每个name并计算兄弟姐妹与该元素出现的次数。

{
    foo: {
        bar: 1,
        baz: 2
    },
    bar: {
        foo: 1,
        baz: 1
    },
    baz: {
        foo: 2,
        bar: 1
    }
}

使用elasticsearch聚合有一种巧妙的方法吗?我对ES中聚合的原始理解让我做了类似的事情:

"aggs": {
    "elements": {
        "nested": {
            "path": "elements"
        },
        "aggs": {
            "names": {
                "terms": {
                    "field": "elements.name",
                    "size": 20
                },
                "aggs": {
                    "more_elements": {
                        "terms": {
                            "field": "elements.name",
                            "size": 20
                        }
                    }
                }
            }
        }
    }
}

这给出了完全错误的结果。我最终得到了类似的东西:

{
    foo: {
        doc_count: 2, 
        foo: 2
    },
    bar: {
        doc_count: 1, 
        foo: 1
    },
    baz: {
        doc_count: 2, 
        foo: 2
    }
}

非常感谢任何帮助!我目前正在使用ES 5.4,如果这很重要的话。

1 个答案:

答案 0 :(得分:0)

无法一步到位地找到方法。 我将它分为两​​个步骤:

第1步:找到所有elements.names:

{
  "size": 0,
  "aggs": {
    "elements": {
      "nested": {
        "path": "elements"
      },
      "aggs": {
        "names": {
          "terms": {
            "field": "elements.name",
            "size": 20
          }
        }
      }
    }
  }
}

第2步:为每个element.name执行:

{
  "size": 0,
  "aggs": {
    "bool_agg": {
      "filter": {
        "bool": {
          "must": {
            "term": {
              "elements.name": "NAME_HERE"
            }
          }
        },
        "aggs": {
          "names": {
            "terms": {
              "field": "elements.name",
              "size": 20
            }
          }
        }
      }
    }
  }
}

注意我在这里没有使用嵌套聚合 - filter aggregation将过滤包含当前名称的每个(完整)文档。我只是得到每个兄弟的出现次数(以及当前的名字 - 但也可以删除)。