Nest ElasticSearch中如何遵循DRY原则添加条件Term查询
在Nest ElasticSearch查询中条件性添加Term过滤(遵循DRY原则)
我明白你现在的困扰——既要根据includeTerminationDate的值动态添加过滤条件,又不想重复写那些基础查询代码违反DRY原则。你之前尝试的三元运算符写法之所以行不通,是因为Nest的查询构建是基于QueryContainer的链式组合,不能直接在逻辑表达式里混写字符串或者不完整的查询片段。
下面是符合DRY原则的解决方案,我们可以分步构建查询:
private Func<QueryContainerDescriptor<EmployeeDocument>, QueryContainer> EmployeeSearchQuery( string query, long companyGroupId, bool includeTerminationDate) { return q => { // 先构建基础查询:MultiMatch 组合 CompanyGroupId 过滤 var baseQuery = q.MultiMatch(m => m .Query(query) .Type(TextQueryType.MostFields) .MinimumShouldMatch("90%") .Fields(f => f .Field(ff => ff.FullName, 3) .Field(ff => ff.Number, 3) .Field(ff => ff.Email) .Field(ff => ff.JobNumber) .Field(ff => ff.Description))) && q.Term(f => f.CompanyGroupId, companyGroupId); // 根据 includeTerminationDate 动态追加过滤条件 if (!includeTerminationDate) { // 排除所有包含 TerminationDate 字段的记录(无论字段值是否为null) baseQuery = baseQuery && !q.Exists(f => f.Field(ff => ff.TerminationDate)); // 如果你需要严格匹配「TerminationDate 为 null」的情况,也可以用以下写法: // baseQuery = baseQuery && q.Term(f => f.TerminationDate, (string)null); } return baseQuery; }; }
代码说明:
- DRY原则体现:基础的
MultiMatch和CompanyGroupId过滤逻辑只写一次,封装在baseQuery变量中,避免重复代码。 - 动态条件处理:通过
if判断includeTerminationDate的值,仅在需要时追加过滤条件——这里用!q.Exists(...)排除所有带有TerminationDate字段的文档;如果你的业务逻辑是仅排除TerminationDate不为null的记录,可以替换成Term查询匹配null值。 - 类型安全:全程基于Nest的强类型查询构建器,避免了之前写法中类型不匹配的问题。
内容的提问来源于stack exchange,提问作者R4nc1d
相关产品推荐
相关产品推荐

