如果没有进一步的aggs被忽略,是否可以将术语聚合嵌套两个以上?

时间:2017-10-19 03:22:38

标签: elasticsearch nest

我正在使用Nest库来查询C#,以获取具有多个支点的图形数据。每个数据透视表都是一个查询的嵌套TermsAggregation,一切正常,只有一个或两个支点。但是,一旦我进入三个枢轴,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 个答案:

答案 0 :(得分:0)

这必须与您构建嵌套聚合的方式有关。与客户Arbitrarily deep nested aggregations can be built。这是一个三深嵌套聚合的例子

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"
              }
            }
          }
        }
      }
    }
  }
}

您还可以直接向AggregationDictionary添加值

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);

答案 1 :(得分:0)

我通过自下而上而不是自上而下构建聚合来使我的代码工作。

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和AggregationDictionary都可以分配给“Aggregations”属性,但是当你以递归方式执行此操作时,似乎有一些微妙的缺陷。

文档也不是最新的:它声称you can create an AggregationDictionary yourself,但由于AggregationDictionary没有公共的Add()方法,我真的不能。我也不能使用C#的{} -after-insantiation语法来填充其属性 - 再次,因为Add()不是公共的。