ElasticSearch 6.0.1-SQL DISTINCT子句-NEST C#

问题描述

我需要使用nesT从文档中返回所有类别的disTINCTS(无重复)。

sql中,它看起来像这样:

  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.8           3         4.35         1.3

在ElasticSearch内部,我这样做:

SELECT disTINCT Category  
  FROM Log  
  ORDER BY Category ASC 

如何使用nesT做到这一点?

GET log/_search
{
  "size":"0","aggs" : {
  "alias_category" : {
  "terms" : { "field" : "category.keyword" }
  }
  }
}

解决方法

我找到了一种方法。这不是一种优雅的方法,但是我在Elastico网站(https://discuss.elastic.co/t/c-nest-best-way-of-accessing-properties-of-iaggregate-object/85384/2)中发现了,并且这样做是这样的:

public ICollection<string> SelectAllCategoriesDistinct(ElasticClient client)
    {
        var searchResponse = 
            client.Search<LogElasticSearch>(s => s
                .Size(0)
                .Aggregations(agg => agg
                    .Terms("categories",t => t
                        .Field("category.keyword")
                    )                  
                )
            );
       
        var aggregation = searchResponse.Aggregations.Values;
        var listOfCategories = new List<string>();

        if (searchResponse.Aggregations.Values.FirstOrDefault().GetType() == typeof(BucketAggregate))
        {
            foreach (IBucket bucket in ((BucketAggregate)aggregation.FirstOrDefault()).Items)
            {
                if (bucket.GetType() == typeof(KeyedBucket<object>))
                {
                    var valueKey = ((KeyedBucket<object>)bucket).Key;
                    listOfCategories.Add(valueKey.ToString());
                }
            } 
        }

        return listOfCategories.OrderBy(c => c).ToList();
    }

如果有人知道更好的方法,请帮助我进行改进,但是那样就可以达到目标。

,

我将使用composite aggregation来获取所有条款。与terms aggregation相比,复合聚合支持分页,因此,如果有 lot 项要提取

,则可以进行多个请求
private static void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var settings = new ConnectionSettings(pool); 
    var client = new ElasticClient(settings);
    
    var categories = new List<string>();

    GetAllCategories(client,categories);
    
    // do something with the categories
    foreach(var category in categories)
        Console.WriteLine(category);
}

private static void GetAllCategories(IElasticClient client,List<string> categories,CompositeKey after = null)
{
    // number of terms to fetch in each request
    var size = 10_000;
    
    var response = client.Search<LogElasticSearch>(s => s
        .Size(0)
        .Aggregations(a => a
            .Composite("categories",c => c
                .After(after)
                .Size(size)
                .Sources(so => so
                    .Terms("category",t => t
                        .Field("category.keyword")
                        .Order(SortOrder.Ascending)
                    )
                )
            )
        )
    );

    var compositeAgg = response.Aggregations.Composite("categories");
    var buckets = compositeAgg.Buckets;

    foreach (var bucket in buckets)
    {
        if (bucket.Key.TryGetValue("category",out string category))
        {
            categories.Add(category);
        }
    }

    // there may be more
    if (buckets.Count == size)
    {
        GetAllCategories(client,categories,compositeAgg.AfterKey);
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...