简体   繁体   English

Nest(ElasticSearch)中的子集/嵌套对象的聚合

[英]Aggregates in Nest (ElasticSearch) on child/nested objects

I have a catalog of products that I want to calculate aggregates on. 我有一个我想要计算聚合的产品目录。 This is simple enough for top level properties such as brand name, manufacturer, etc. The trouble comes with trying to calculate range counts on prices because we sell in multiple currencies, and when determining these counts I only want to query on one currency at a time. 这对于顶级属性(如品牌名称,制造商等)来说非常简单。尝试计算价格的范围计数时会出现问题,因为我们以多种货币进行销售,并且在确定这些计数时我只想查询一种货币。时间。 Here is a sample of my product object mapping: 以下是我的产品对象映射示例:

public class Product
{
    public int ID { get; set;}
    public string Name { get; set; }
    public IList<Price> Prices { get; set; }
}

public class Price
{
    public int CurrencyID { get; set; }
    public decimal Cost { get; set; }
}

Here is an example of a query for all products with a price below 100: 以下是价格低于100的所有产品的查询示例:

var cheapProducts = client.Search<Product>(s => s
    .From(0)
    .Size(1000)
    .Query(q => q
        .Range(r => r
            .LowerOrEquals(100)
            .OnField(f => f.Prices.FirstOrDefault().Cost))));

The ElasticSearch request that this generates is: 这会生成的ElasticSearch请求是:

{
    "from": 0,
    "size": 1000,
    "query": {
        "range" : {
            "prices.cost": {
                "lte": "100"
            }
        }
    }
}

This returns all products with at least one price below 100 in any currency, as you would expect. 如您所料,这将以任何货币返回至少一个价格低于100的产品。 What I've been unable to do is to run this query against just prices in a given currency. 我无法做的是针对给定货币的价格运行此查询。 For example, adding this filter to the query only removes products that don't have a price in currency 1: 例如,将此过滤器添加到查询中只会删除货币1中没有价格的产品:

var cheapProducts = client.Search<Product>(s => s
    .From(0)
    .Size(1000)
    .Filter(f => f
        .Term(t => t
            .Prices.FirstOrDefault().CurrencyID, 1))
    .Query(q => q
        .Range(r => r
            .LowerOrEquals(100)
            .OnField(f => f.Prices.FirstOrDefault().Cost))));

I've tried treating the Prices list as both a nested object and a child object, but ElasticSearch doesn't appear to be indexing the prices in that way because I get an error of "AggregationExecutionException[[nested] nested path [prices] is not nested]" and similar for HasChild queries. 我已经尝试将价格列表视为嵌套对象和子对象,但ElasticSearch似乎没有以这种方式索引价格,因为我收到错误“AggregationExecutionException [[嵌套]嵌套路径[价格]是不嵌套]“和HasChild查询类似。 Is it possible to generate queries and aggregates in this way? 是否可以以这种方式生成查询和聚合?

First you need to map the nested type: 首先,您需要映射嵌套类型:

 public class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
   [ElasticProperty(Type = FieldType.Nested)]
    public IList<Price> Prices { get; set; }
}

After that, try execute this query: 之后,尝试执行此查询:

 var cheapProducts = client.Search<Product>(s => s
            .From(0)
            .Size(1000)
            .Query(x => x.Term(p => p
                .Prices.First().CurrencyID, 1) && x.Range(r => r
                    .LowerOrEquals(100)
                    .OnField(f => f.Prices.FirstOrDefault().Cost))));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM