c# - Elasticsearch Nest 动态聚合

标签 c# elasticsearch nest

我试图在 c# 中运行聚合查询(使用 nest 5)但是 我不知道有多少聚合作为输入以及聚合类型是什么。

例如一个查询是: {"aggs":{"type_count":{"terms":{"field":"type"}}}}

其他查询将是: {"aggs":{"type_count":{"terms":{"field":"type"}},"salary_count": {“字段”:“薪水”}}}

而其他查询可能根本不包含聚合。

如何在 C# 中动态编写此代码?

这是我尝试过的(我有选择聚合类型的案例。 问题在于此代码仅支持一种聚合。

SearchDescriptor<object> SearchAgg = new SearchDescriptor<object>();
for (i=0;i < aggList.length;i++)
{
    SearchAgg.Aggregations(a => a.terms (aggList[i]), t=> t.Field(aggList[i]));
}

编辑:

我使用此代码成功添加了多个聚合:

AggregationContainerDescriptor<SearchRequest> agg = new
AggregationContainerDescriptor<SearchRequest>();

agg.Terms("bucket", tm=> tm.Field("field"));
agg &= new AggregationContainerDescriptor<SearchRequest>().Terms("bucket2", tm=> tm.Field("field2"));

谢谢

最佳答案

一般来说,在 NEST 中使用 Fluent lambda 表达式语法的方法调用执行赋值而不是添加,这意味着同一方法的连续调用将覆盖赋值的内容。在你这里的例子中

SearchDescriptor<object> SearchAgg = new SearchDescriptor<object>();
for (i=0;i < aggList.length;i++)
{
    SearchAgg.Aggregations(a => a.terms (aggList[i]), t=> t.Field(aggList[i]));
}

只有最后一次调用 SearchAgg.Aggregations(...) 才会分配。

writing aggregations documentation有发布多个聚合的例子。给定以下 POCO

public class Project
{
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime StartedOn { get; set; }
    public DateTime LastActivity { get; set; }
    public IList<string> Tags { get; set; }
    public IList<string> Branches { get; set; }
    public IList<CommitActivity> Commits { get; set; }
}

public class CommitActivity
{
    public string Id { get; set; }
    public string Message { get; set; }
    public long SizeInBytes { get; set; }
}

其中 CommitActivity 被映射为 nested 类型,发出两个术语聚合和一个嵌套的提交聚合,以聚合有关每个项目的提交的统计信息

使用流畅的 lambda 表达式语法

var searchResponse = client.Search<Project>(s => s
    .Aggregations(aggs => aggs
        .Terms("project_tags", t => t.Field(p => p.Tags))
        .Terms("project_branches", t => t.Field(p => p.Branches))
        .Nested("commits", n => n
            .Path(p => p.Commits)
            .Aggregations(aa => aa
                .Stats("commit_size_stats", m => m.Field(p => p.Commits.First().SizeInBytes))
            )
        )
    )
);

对象初始化语法

var searchRequest = new SearchRequest<Project>
{
    Aggregations = new AggregationDictionary
    {
        { "project_tags", new TermsAggregation("project_tags") { Field = Nest.Infer.Field<Project>(p => p.Tags) } },
        { "project_branches", new TermsAggregation("project_branches") { Field = Nest.Infer.Field<Project>(p => p.Branches) } },
        { "commits", new NestedAggregation("commits") 
            {
                Path = Nest.Infer.Field<Project>(p => p.Commits),
                Aggregations = new AggregationDictionary
                {
                    { "commit_size_stats", new StatsAggregation("commit_size_stats", Nest.Infer.Field<Project>(p => p.Commits.First().SizeInBytes)) },
                }
            }
        }
    }
};

var searchResponse = client.Search<Project>(searchRequest);

由于最终搜索请求上的聚合只是聚合名称和聚合类型的字典,因此使用此语法可以很快变大。出于这个原因,NEST 重载了逻辑 && 运算符并实现了隐式转换,以允许以更简洁的方式组合聚合

简洁的对象初始化语法

var searchRequest = new SearchRequest<Project>
{
    Aggregations = 
        new TermsAggregation("project_tags") { Field = Nest.Infer.Field<Project>(p => p.Tags) } &&
        new TermsAggregation("project_branches") { Field = Nest.Infer.Field<Project>(p => p.Branches) } &&
        new NestedAggregation("commits") 
        {
            Path = Nest.Infer.Field<Project>(p => p.Commits),
            Aggregations = 
                new StatsAggregation("commit_size_stats", Nest.Infer.Field<Project>(p => p.Commits.First().SizeInBytes))
        }
};

var searchResponse = client.Search<Project>(searchRequest);

关于c# - Elasticsearch Nest 动态聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45212980/

相关文章:

c# - 为什么在 C# 中使用 String.Concat()?

c# - 保持 ASP.NET session 打开/事件

docker - EKS-Kubernetes-ES-错误:elasticsearch过程的最大文件描述符[4096]太低,至少增加到[65536]

elasticsearch - Elasticsearch/Nest-组合多个范围查询(OIC语法)

elasticsearch - 如何从映射中排除继承的对象属性

c# - 在Windows 7中设置采样率

c# - 为什么在远程 WCF 和本地运行的 wmi 查询中会得到不同的结果?

elasticsearch - ElasticSearch NEST-搜索多种类型,但仅对所选类型应用过滤器

kibana - elasticsearch/kibana 错误“数据太大,[@timestamp] 的数据将大于限制

c# - Elasticsearch - 排序搜索结果 ASC