等价linq查询

wljmcqd8  于 2021-06-14  发布在  ElasticSearch
关注(0)|答案(2)|浏览(401)

我有以下弹性文件类型:

public class ProductDto
{
   public Int64 Id { get; set; }

   public String Title{ get; set; }

   public bool Visible { get; set; }

   public IList<ProductSupplierDto> ProductSuppliers { get; set; }
}

public class ProductSupplierDto
{
   public Int64 Id { get; set; }

   public String Title{ get; set; }

   public bool Enabled { get; set; }
}

如何使用nest Library编写以下linq查询:

var products = db.products.where(p=>  p.Visible 
                                   && p.ProductSuppliers.Any(ps=>ps.Enabled)
                                 ).ToList();

在nest library中,我有以下查询:

var baseQuery = Query<ProductDto>.Term(qt => qt.Field(f => 
                                      f.Visible).Value(true));

如何将productsuppliers筛选器添加到basequery?
我使用此方法创建索引:

private async Task CreateIndexIfItDoesntExist<T>(string index) where T: class
    {
        if (!this.client.IndexExists(index).Exists)
        {
            var indexDescriptor = new CreateIndexDescriptor(index)
                            .Settings(x => x.NumberOfReplicas(0))
                            .Mappings(mappings => mappings
                                .Map<T>(m => m.AutoMap()));

            await this.client.CreateIndexAsync(index, i => indexDescriptor);

       // Max out the result window so you can have pagination for >100 pages
           await this.client.UpdateIndexSettingsAsync(index, ixs => ixs
             .IndexSettings(s => s
                 .Setting("max_result_window", int.MaxValue)));

        }
    }

并这样称呼:

await CreateIndexIfItDoesntExist<ProductDto>("products");

索引数据的方法:

private async Task<IndexResult> IndexDocuments<T>(T[] datas, string index) where T:class
    {
        int batchSize = 1000; // magic
        int totalBatches = (int)Math.Ceiling((double)datas.Length / batchSize);

        for (int i = 0; i < totalBatches; i++)
        {
            var response = await this.client.IndexManyAsync(datas.Skip(i * batchSize).Take(batchSize), index);

            if (!response.IsValid)
            {
                return new IndexResult
                {
                    IsValid = false,
                    ErrorReason = response.ServerError?.Error?.Reason,
                    Exception = response.OriginalException
                };
            }
            else
            {
                Debug.WriteLine($"Successfully indexed batch {i + 1}");
            }
        }

        return new IndexResult
        {
            IsValid = true
        };
    }
chhkpiq4

chhkpiq41#

像这样的?

QueryContainer baseQuery = Query<ProductDto>.Term(qt => qt.Field(f =>
                                   f.Visible).Value(true));
        baseQuery &= Query<ProductDto>.Term(qt => qt.Field(o => o.ProductSuppliers.Select(a => a.Enabled)).Value(true));

        client.Search<ProductDto>(o => o
           .From(0)
           .Size(10)
           .Query(a => baseQuery));
hs1rzwqc

hs1rzwqc2#

ProductSupplierDtoProductSuppliers 将Map为 object 使用automapping键入,这样下面的查询将实现您所要的

var client = new ElasticClient();

var searchResponse = client.Search<ProductDto>(s => s
    .Query(q => +q
        .Term(f => f.Visible, true) && +q
        .Term(f => f.ProductSuppliers[0].Enabled, true)
    )    
);

这将生成以下查询

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "visible": {
              "value": true
            }
          }
        },
        {
          "term": {
            "productSuppliers.enabled": {
              "value": true
            }
          }
        }
      ]
    }
  }
}

几点
查询对查询使用运算符重载,将它们组合在一起,并生成在筛选器上下文中执行的查询(在本例中,是 bool 查询 filter 条款)。因为文档要么匹配要么不匹配,所以不需要计算匹配的相关性得分。 f => f.ProductSuppliers[0].Enabled 是获取字段路径的表达式。它并不意味着“获得 Enabled 从中的第一项开始 ProductSuppliers ,但意思是“找到通往 Enabled 中所有项的字段 ProductSuppliers “财产”。这里的索引器只能访问集合的属性 ProductSupplierDto 类型。
您可能需要考虑Map ProductSuppliers 作为一个 nested 键入,以便能够跨 ProductSuppliers 收藏。与 ProductSuppliers Map为 nested 类型,则查询将

var searchResponse = client.Search<ProductDto>(s => s
    .Query(q => +q
        .Term(f => f.Visible, true) && +q
        .Nested(n => n
            .Path(p => p.ProductSuppliers)
            .Query(nq => nq
                .Term(f => f.ProductSuppliers[0].Enabled, true)
            )
        )           
    )    
);

相关问题