2

使用 .NET 的 Elasticsearch NEST 库我正在尝试创建一个搜索产品的查询。该模型的结构如下:

[ElasticsearchType(Name = "product", IdProperty = "ProductId")]
public class ProductIndex
{
    [Number(NumberType.Integer)]
    public int ProductId { get; set; }

    [Text]
    public string Name { get; set; }

    [Text]
    public string Description { get; set; }

    [Number(NumberType.Integer)]
    public int BranchId { get; set; }

    [Number(NumberType.Integer)]
    public int SubbranchId { get; set; }

    [Number(NumberType.Float)]
    public decimal Rating { get; set; }

    [Boolean]
    public bool IsActive { get; set; }

    [Date]
    public DateTime PublishedAt { get; set; }

    [Nested]
    public ICollection<VariantIndex> Variants { get; set; }
}

[ElasticsearchType(Name = "variant", IdProperty = "VariantId")]
public class VariantIndex
{
    public int VariantId { get; set; }
    public decimal Price { get; set; }
    public IEnumerable<string> Values { get; set; }
}

我需要根据以下参数过滤产品:

  • branchId(int):产品BranchId等于branchId参数,
  • subbranches (int[]):产品 SubbranchId 包含在 subbranches 数组中
  • rating(int):产品Rating大于等于rating参数
  • minPrice (int):产品变体价格大于 minPrice 参数
  • maxPrice (int):产品变体价格小于 maxPrice 参数
  • searchTerm(字符串):产品名称或描述包含字符串 searchTerm
  • tags (string[]):产品变体值包含一个或多个或所有标签。

注意:branchIdsubbranchesratingsearchTerm应该过滤掉顶级 ProductIndex 对象。然后,minPricemaxPrice参数应该过滤掉任何嵌套的 Variants 对象,如果它们的 Price 不在指定范围内,最后tags参数应该过滤掉任何不包含其 Values 数组中的任何标签的嵌套 Variants 对象或对它们进行评分根据在 Values 数组中匹配的标签数量适当地进行。

最终结果应该是评分的 ProductIndex 对象的列表,每个对象都包含一个过滤掉和评分的 VariantIndex 对象的列表。


这是我尝试创建查询的方式,但这给了我完全错误的搜索结果:

Func<SearchDescriptor<ProductIndex>, ISearchRequest> search = s => s
            .From(page * 10)
            .Size(10)
            .Query(q => q
                .Bool(b => b
                    .Must(mu => mu
                        .Match(m => m
                            .Field(f => f.Name)
                            .Query(searchTerm)
                        ), mu => mu
                        .Match(m => m
                            .Field(f => f.Description)
                            .Query(product)
                        ), mu => mu
                        .Terms(t => t
                            .Field(f => f.Variants.Select(v => v.Values))
                            .Terms(tags)
                        )
                    )
                    .Filter(bf => bf
                        .Term(t => t
                        .Field(p => p.BranchId)
                        .Value(mainbranch))
                     )
                    .Filter(bf => bf
                            .Terms(t => t
                            .Field(p => p.SubbranchId)
                            .Terms(subbranches)
                        )
                    )
                    .Filter(bf => bf
                        .Range(r => r
                            .Field(f => f.Variants.Select(v => v.Price))
                            .GreaterThanOrEquals(minPrice)
                            .LessThanOrEquals(maxPrice)
                        )
                    )
                )
            );


        var response = await client.SearchAsync<ProductIndex>(search);

编辑1: 根据我自己调查的评论,我终于设法创建了一个正常工作的查询。剩下要做的就是过滤掉嵌套的 VariantIndex 对象列表,以便我们只获得符合价格标签过滤器的变体。为了实现这一点,我应该将什么代码添加到我的最新工作版本的查询中?

Func<SearchDescriptor<ProductIndex>, ISearchRequest> search = s => s.Type<ProductIndex>()
            .Query(q => q
                .Bool(b => b
                    .Must(m => m
                        .MultiMatch(mm => mm
                            .Query(product)
                            .Fields(f =>
                                f.Fields(f1 => f1.Name, f2 => f2.Description)
                            )
                        )
                    )
                    .Should(ss => ss
                        .Match(m => m
                            .Field(f => f.Variants.Select(v => v.Values))
                            .Query(tagsJoined)
                        )
                    )
                    .Filter(m => m
                        .Bool(bl => bl
                            .Must(ms => ms
                                .Range(r => r
                                    .Field(f => f.Rating)
                                    .GreaterThanOrEquals(rating)
                                ),
                                ms => ms
                                    .Range(r => r
                                        .Field(f => f.Variants.Select(v => v.Price))
                                        .GreaterThanOrEquals(minPrice)
                                        .LessThanOrEquals(maxPrice)
                                    )
                            )
                        )

                    )
                )

            )
4

0 回答 0