使用.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 , 子分支 , 评分 < / strong>和 searchTerm 应过滤掉顶级的ProductIndex对象。然后, minPrice 和 maxPrice 参数应过滤掉任何嵌套的Variants对象,如果它们的价格不在指定的位置范围,最后 标记 参数应过滤掉任何不包含其Values数组中任何标记的嵌套Variants对象,或根据标记的数量对其进行适当评分。在数组数组中匹配。
最终结果应该是已评分的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)
)
)
)
)
)
)