在子/嵌套对象的 Nest (ElasticSearch) 中进行聚合

本文关键字:ElasticSearch 嵌套 对象 Nest 在子 | 更新日期: 2023-09-27 18:34:20

我有一个产品目录,我想计算聚合。 这对于品牌名称、制造商等顶级属性来说非常简单。 尝试计算价格的范围计数会带来麻烦,因为我们以多种货币出售,并且在确定这些计数时,我一次只想查询一种货币。 以下是我的产品对象映射示例:

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

下面是价格低于 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))));

由此生成的 ElasticSearch 请求是:

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

正如您所期望的那样,这将返回至少一个价格低于 100 的任何货币的所有产品。 我无法做的是仅针对给定货币的价格运行此查询。 例如,将此筛选器添加到查询只会删除没有货币 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))));

我尝试将价格列表视为嵌套对象和子对象,但 ElasticSearch 似乎没有以这种方式索引价格,因为我收到错误"AggregationExecutionException[[嵌套] 嵌套路径 [价格] 未嵌套]"和类似的 HasChild 查询。 是否可以以这种方式生成查询和聚合?

在子/嵌套对象的 Nest (ElasticSearch) 中进行聚合

首先,您需要映射嵌套类型:

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

之后,尝试执行此查询:

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