如何用Elasticsearch .NET 8.3客户端动态构建Should子句查询
在Elasticsearch .NET客户端中使用字符串列表构建Should子句
当然可以用字符串列表替代硬编码值来构建Should子句,甚至更推荐用Terms查询实现这种多值OR匹配(相比多个Term查询的Should组合,性能更优)。以下是两种可行方案:
方案1:用字符串列表生成多个Term查询放入Should子句
先定义目标值列表,再通过LINQ将每个值转换为Term查询,传入Should方法:
public async Task<SearchResponse<SubmissionDto>> GetRapbacksAsync(DateTime startDate, DateTime endDate, string destination) { // 定义需要匹配的Tot值列表,统一转小写 var targetTotValues = new List<string> { "RBIHS", "RBMNT", "RBSCRM", "RBN", "RBSCVL", "RBRPT", "RBRPTR" } .Select(v => v.ToLower()) .ToList(); ElasticsearchClient localClient = GetClient(destination); var rapbacks = await localClient.SearchAsync<SubmissionDto>(SUBMISSION_INDEX, s => s .Query(q => q .Bool(b => b .Should(targetTotValues.Select(value => new TermQuery { Field = Infer.Field<SubmissionDto>(f => f.Tot), Value = value })) .MinimumShouldMatch(1) .Must(ss => ss.Range(rr => rr .DateRange(dr => dr .Field(f => f.SubmissionCreation) .Gte(startDate.ToString("yyyy/MM/dd")) .Lte(endDate.ToString("yyyy/MM/dd")) )))) .Size(MAX_DOCUMENTS) .Sort(sort => sort.Field(f => f.SubmissionCreation, d => d.Order(SortOrder.Desc))) ); return rapbacks; }
方案2:使用Terms查询(更优)
Terms查询本身就是实现“匹配字段值为列表中任意一个”的逻辑,等价于多个Term查询的Should组合,但查询效率更高,代码也更简洁:
public async Task<SearchResponse<SubmissionDto>> GetRapbacksAsync(DateTime startDate, DateTime endDate, string destination) { var targetTotValues = new List<string> { "RBIHS", "RBMNT", "RBSCRM", "RBN", "RBSCVL", "RBRPT", "RBRPTR" } .Select(v => v.ToLower()) .ToList(); ElasticsearchClient localClient = GetClient(destination); var rapbacks = await localClient.SearchAsync<SubmissionDto>(SUBMISSION_INDEX, s => s .Query(q => q .Bool(b => b .Must( // 用Terms查询替代多个Term的Should ss => ss.Terms(t => t.Field(f => f.Tot).Terms(targetTotValues)), ss => ss.Range(rr => rr .DateRange(dr => dr .Field(f => f.SubmissionCreation) .Gte(startDate.ToString("yyyy/MM/dd")) .Lte(endDate.ToString("yyyy/MM/dd")) )) )) .Size(MAX_DOCUMENTS) .Sort(sort => sort.Field(f => f.SubmissionCreation, d => d.Order(SortOrder.Desc))) ); return rapbacks; }
注意事项
- 以上代码针对Elastic.Clients.Elasticsearch(.NET生态最新的官方Elasticsearch客户端,取代旧版NEST),语法和NEST有差异,需注意区分客户端版本。
- 使用Terms查询时,无需设置
MinimumShouldMatch(1),因为Terms查询默认就是匹配列表中任意一个值即可。
内容的提问来源于stack exchange,提问作者Tiffany Lynn
相关产品推荐
相关产品推荐

