使用 .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[]):产品变体值包含一个或多个或所有标签。
注意:branchId、subbranches、rating和searchTerm应该过滤掉顶级 ProductIndex 对象。然后,minPrice和maxPrice参数应该过滤掉任何嵌套的 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)
)
)
)
)
)
)