【问题标题】:c# Nest and Elasticsearch Aggregationsc# Nest 和 Elasticsearch 聚合
【发布时间】:2019-02-27 04:03:34
【问题描述】:

有谁知道如何使用嵌套进行多个聚合? 我发现了很多例子,不幸的是它们都不起作用。

这是我所拥有的:

Vehicles fields = new Vehicles();

//create a terms query
var query = new TermsQuery
{
    IsVerbatim = true,
    Field = "VehicleOwnerId",
    Terms = new string[] { 25 },
};

var aggregations = new Dictionary<string, IAggregationContainer>
{
    { "years", new AggregationContainer
        {
            Terms = new TermsAggregation(nameof(fields.Year))
            {
                Field = new Field(nameof(fields.Year))
            }
        }
    }
    //,
    //{ "makes", new AggregationContainer
    //    {
    //        Terms = new TermsAggregation("Make")
    //        {
    //            Field = new Field(nameof(fields.Make))
    //        }
    //    }
    //}
};

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 100,
    Aggregations = aggregations
};

var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;

var years = result.Aggregations.Terms("years");
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
    yearCounts.Add(item.Key, item.DocCount ?? 0);
}

如果我像这样执行代码,它就可以工作。 Years 按预期返回聚合。如果我尝试添加另一个字段(如上面注释掉的那个),它会失败并且我得到零记录。 如何在一个查询中获取多个聚合?我到处都看到了它的例子,但我尝试过的例子似乎都不起作用,而且大多数似乎已经过时(包括 Nest 文档中的一些例子)。 我也尝试过这种非常接近文档的方法。

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 100,
    //Aggregations = aggregations
    Aggregations = new AggregationDictionary
    {
        { 
            "childAgg", new ChildrenAggregation("childAgg", typeof(Vehicles ))
            {
                Aggregations = new AggregationDictionary
                {
                    {"years", new TermsAggregation(nameof(fields.VehicleYear))},
                    {"makes", new TermsAggregation(nameof(fields.VehicleMakeName))},
                    {"models", new TermsAggregation(nameof(fields.VehicleModelName))},
                }
            }
        }
    }
};

var result = client.SearchAsync<Vehicles>(searchRequest).Result;

这只会产生一个空引用异常。

【问题讨论】:

  • 哪些 NEST 文档已过时?你见过elastic.co/guide/en/elasticsearch/client/net-api/current/…
  • 我认为该页面已过时。它显示了这个例子: new MaxAggregation("max_per_child", Field(p => p.ConfidenceFactor)) 应该是 MaxAggregation("max_per_child", new Field("ConfidenceFactor")) 或者尽可能地租赁告诉。
  • 现在,当我尝试页面中的一个示例时,我看到了一个错误。错误是“类型:null_pointer_exception 原因:”“”不确定它为什么会发生或这意味着什么。
  • 页面上的文档是从测试源代码生成的:github.com/elastic/elasticsearch-net/blob/… 这些测试在每次签入时运行,以通知客户端代码是否存在编译错误或更改,以便最终,文档与该分支中的最新客户端代码保持一致。在这种情况下,我看不到文档有任何问题,但如果您确实遇到了一些问题,请随时在 github.com/elastic/elasticsearch-net/issues 上打开问题,以便我们解决
  • 似乎对我不起作用的代码是术语聚合的一个示例。它显示 `Field = Field(p => p.State)` 但我无法让 Field 工作。但是,字段(字符串)工作得很好。我不记得确切的错误,但它只是没有识别它。谢谢你提供的信息——我可能做错了什么。

标签: c# elasticsearch nest


【解决方案1】:

我想我永远不会太担心作为一名程序员而自豪:) 问题的解决方案常常让我觉得自己很愚蠢。

所以我的问题是我试图在聚合中使用的字段是文本,无法使用。我将所有内容都切换到 ID 字段,并且多个聚合按预期工作。

所以这个版本的代码就像一个冠军:

Vehicle fields = new Vehicle ();

//create a terms query
var query = new TermsQuery
{
    IsVerbatim = true,
    Field = "VehicleOwnerId",
    Terms = new string[] { "30" },
};

string[] Fields = new[]
{
    nameof(fields.Year),
    nameof(fields.MakeId),
    nameof(fields.ModelId)
};

var aggregations = new Dictionary<string, IAggregationContainer>();
foreach (string sField in Fields)
{
    var termsAggregation = new TermsAggregation(sField)
    {
        Field = sField
    };

    aggregations.Add(sField, new AggregationContainer { Terms = termsAggregation });
}

//create the search request
var searchRequest = new SearchRequest
{
    Query = query,
    From = 0,
    Size = 10,
    Aggregations = aggregations
};

var result = client.SearchAsync<InventoryLiveView>(searchRequest).Result;

var years = result.Aggregations.Terms(nameof(fields.Year));
Dictionary<string, long> yearCounts = new Dictionary<string, long>();
foreach (var item in years.Buckets)
{
    yearCounts.Add(item.Key, item.DocCount ?? 0);
}

我使用邮递员看到的来自 elasticsearch 的确切错误是:

Fielddata is disabled on text fields by default. Set fielddata=true on [MakeName] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.

【讨论】:

    【解决方案2】:

    这是我使用 SearchDescriptors 的示例。我唯一的问题是如何将返回的结果序列化为正确的键值列表。遍历字段列表是返回结果的最佳方式吗?

    SearchDescriptor<Advert> agghDescriptor = new SearchDescriptor<Advert>();
    
    agghDescriptor.Aggregations(ag => ag.Terms("make", a => a.Field(f => f.Make)) &&
                                      ag.Terms("region", a => a.Field(f => f.Region)) &&
                                      ag.Terms("city", a => a.Field(f => f.City)) &&
                                      ag.Terms("category", a => a.Field(f => f.Category)) &&
                                      ag.Terms("application", a => a.Field(f => f.Application)) &&
                                      ag.Terms("portalId", a => a.Field(f => f.PortalId)) &&
                                      ag.Terms("isActiveAuctionAdvert", a => a.Field(f => f.IsActiveAuctionAdvert)) &&
                                      ag.Terms("isBargainAccount", a => a.Field(f => f.IsBargainAccount)) &&
                                      ag.Terms("condition", a => a.Field(f => f.Condition))
    );
    agghDescriptor.Size(0);
    
    var json2 = _client.RequestResponseSerializer.SerializeToString(agghDescriptor);
    var aggregationResult = _client.Search<Advert>(agghDescriptor);
    
    List<string> fields = new List<string>();
    fields.Add("make");
    fields.Add("category");
    fields.Add("region");
    
    List<Aggregation> aggregations = new List<Aggregation>();
    
    foreach (var field in fields)
    {
        var aggrs = aggregationResult.Aggregations.Terms(field);
        List<AggregateItem> aggregateItems = new List<AggregateItem>();
        
        foreach (var item in aggrs.Buckets)
        {
            aggregateItems.Add(new AggregateItem()
            {
                Count = item.DocCount ?? 0,
                Key = item.Key
            });
        }
    
        aggregations.Add(new Aggregation()
        {
            Name = field,
            Aggregates = aggregateItems
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2014-09-17
      • 1970-01-01
      • 2020-01-23
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多