当前位置: 首页 > 知识库问答 >
问题:

如果不忽略进一步的AGG,不能嵌套超过两个深度的术语聚合吗?

冷翼
2023-03-14

我正在使用C#的Nest库查询ElasticSearch,以获取具有多个透视点的图形数据。每个透视点都是查询上的嵌套TermsAg聚集,一两个透视点一切正常。但是,一旦我达到三个透视点,SearchRequest对象就不会生成进一步的聚合。

构建聚合的代码如下所示:

TermsAggregation topTermAgg = null;
TermsAggregation currentAgg = null;
foreach (var pivotName in activePivots)
{
    newTermAgg = new TermsAggregation("pivot")
    {
        Field = pivot.ToString().ToLower()
    };

    if (topTermAgg == null)
    {
        topTermAgg = newTermAgg;
    }
    else
    {
        currentAgg.Aggregations = newTermAgg;
    }
    currentAgg = newTermAgg;
}

SearchRequest本身非常简单:

var searchRequest = new SearchRequest(Indices.Index("a", "b", "c"))
{
    Size = 0,
    Aggregations = topTermAgg,
    Query = query,
};

不幸的是,当转换为字符串时,3个或更多数据透视的SearchRequest如下(通过nestClient.Serializer.SerializeToString(SearchRequest)):

{
  "size": 0,
  "query": {
    "bool": <Fairly complex query, that works fine. It's the aggregation that has the problem.>
  },
  "aggs": {
    "pivot": {
      "terms": {
        "field": "pivot1"
      },
      "aggs": {
        "pivot": {
          "terms": {
            "field": "pivot2"
          }
        }
      }
    }
  }
}

当我在调试器中检查searchRequest对象时,它肯定有3个或更多聚合。这里发生了什么,如何让3个或更多嵌套术语聚合正常工作?

我使用的是Nest版本5.01。

共有2个答案

饶元章
2023-03-14

我通过自下而上而不是自上而下构建聚合来运行代码。

var terminalAggregation = <some aggregation. In my code, there's a lowest aggregation that's different from the rest. For the code I presented, you could just build the lowest pivot.>
TermsAggregation topTermAgg = null;
activePivots.Reverse();
foreach (var pivotName in activePivots)
{
    newTermAgg = new TermsAggregation("pivot")
    {
        Field = pivot.ToString().ToLower(),
        Aggregations = topTermAgg ?? terminalAggregation
    };

    topTermAgg = newTermAgg;
}

这看起来像Nest库中的一个错误;有不同的类,如AggregationBase和BucketAggregationBase和AggregationDicpedia,它们都可以分配给“Aggregations”属性,但当您递归地执行此操作时,第二次分配后似乎存在一些微妙的缺陷。

文档也不是最新的:它声称您可以自己创建AggregationDictionary,但由于AggregationDictionary没有公共的Add()方法,我真的不能。我也不能使用C#'s{}(在初始化语法之后)来填充其属性,因为Add()不是公共的。

刘瑞
2023-03-14

这必须与构建嵌套聚合的方式有关。可以使用客户端构建任意深度嵌套聚合。这是一个三个深度嵌套聚合的示例

client.Search<Question>(s => s
    .Aggregations(a => a
        .Terms("top", ta => ta
            .Field("top_field")
            .Aggregations(aa => aa
                .Terms("nested_1", nta => nta
                    .Field("nested_field_1")
                    .Aggregations(aaa => aaa
                        .Terms("nested_2", nnta => nnta
                            .Field("nested_field_3")
                        )
                    )
                )
            )
        )
    )
);

将其序列化为

{
  "aggs": {
    "top": {
      "terms": {
        "field": "top_field"
      },
      "aggs": {
        "nested_1": {
          "terms": {
            "field": "nested_field_1"
          },
          "aggs": {
            "nested_2": {
              "terms": {
                "field": "nested_field_3"
              }
            }
          }
        }
      }
    }
  }
}

您还可以直接向AggregationDicpedia添加值

var request = new SearchRequest<Question>
{
    Aggregations = new AggregationDictionary
    {
        { "top", new TermsAggregation("top")
            {
                Field = "top_field",
                Aggregations = new AggregationDictionary
                {
                    { "nested_1", new TermsAggregation("nested_1")
                        {
                            Field = "nested_field_1",
                            Aggregations = new AggregationDictionary
                            {
                                { "nested_2", new TermsAggregation("nested_2")
                                    {
                                        Field = "nested_field_2"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
};

client.Search<Question>(request);

与前面的请求相同。您可以将其进一步缩短为

var request = new SearchRequest<Question>
{
    Aggregations = new TermsAggregation("top")
    {
        Field = "top_field",
        Aggregations = new TermsAggregation("nested_1")
        {
            Field = "nested_field_1",
            Aggregations = new TermsAggregation("nested_2")
            {
                Field = "nested_field_2"
            }
        }
    }
};

client.Search<Question>(request);
 类似资料:
  • 问题内容: 示例文档中有一个简化的文档。这对我理解非嵌套类型与嵌套类型的聚合差异很有帮助。但是,这种简化掩盖了进一步的复杂性,因此我不得不在这里扩展这个问题。 所以我的实际文件更接近以下内容: 因此,我保留了,和的关键属性,但隐藏了许多其他使情况复杂化的内容。首先,请注意,与引用的问题相比,有很多额外的嵌套:在根和“项目”之间,以及在“项目”和“ item_property_1”之间。此外,还请注

  • Elasticsearch版本:2.3.3 基本上,标题说明了一切。如果二个嵌套聚合下使用reverse_nested,尽管文档似乎通过限定范围(请参阅结果中的最后一个字段),但其后面的聚合不会以某种方式工作。 这里我准备了一个例子——一个文档是一个学生的注册日期和考试历史。 映射: 试验文件: 聚合查询(无实际意义): 结果是: ...您可以在其中看到聚合“newest_exam_date”不起

  • 我有一个索引,,我需要将其聚合到每年的桶中,然后进行排序。 我已经成功地使用Bucket Sort按简单的和值(

  • 问题内容: 我在elasticsearch(YML中的定义)中具有字段的下一个映射: 每个文档都有很多过滤器,看起来像: 我试图获取唯一过滤器名称的列表以及每个过滤器的唯一过滤器值的列表。 我的意思是,我想获得结构是怎样的:Rahmengröße: 39.5厘米 45.5厘米 33.5厘米 颜色: 盖尔布 为了得到它,我尝试了几种聚合的变体,例如: 这个请求是错误的。 它将为我返回唯一过滤器名称的

  • 我在elasticsearch中对嵌套字段使用复合聚合,但我想从结果中排除一些术语。 此聚合正在工作: 但是我想从stk2中排除一些术语, 上述查询不起作用。 更新1:结果应该只省略数组元素,而不是包含“cancel”的整个文档。 我使用的是弹性v6.7

  • 我有一个存储字符串数组的字段。不同的文档包含不同的字符串集。 现在,我使用这个聚合查询来分析每个文件类型的使用情况。 结果与预期一致。但最近我在删除XML文件支持后更新了此字段。因此,文档的non具有文件类型XML。我可以从这个查询中确认这一点。 总命中计数为零。奇怪的是,当我再次执行上述聚合查询时,我仍然可以将XML视为一个术语。doc count为零。 如果这个XML术语在任何文档中都不存在,