C#使用NEST库调用Elasticsearch时如何为LINQ语句添加条件逻辑
问题根因
你代码中对QueryContainerDescriptor<Product>的强制转换是问题核心:NEST的查询描述符调用Match/Range/Terms等查询方法后,返回的是QueryContainer类型,而非原描述符类型,使用as强转会直接得到null,导致你所有对查询条件的赋值都失效,所以最终生成的请求没有查询规则。而Source部分的字段排除操作返回的仍然是原描述符类型,所以可以正常运行。
修复方案
直接用QueryContainer类型累计查询条件即可,不需要强转回描述符,修改后的代码如下:
var products = await client.SearchAsync<Product>(x => { x = x.Query(q => { // 声明QueryContainer变量累计查询条件 QueryContainer query = null; if (request.IsAvailable.HasValue) { query &= q.Match(b => b.Field(bm => bm.IsAvailable).Query(request.IsAvailable.Value ? "true" : "false")); } if (request.MinPrice.HasValue || request.MaxPrice.HasValue) { query &= q.Range(r => { // 仅指定一次Field,重复调用会覆盖之前配置 r.Field(f => f.Price); if (request.MinPrice.HasValue) { r.GreaterThanOrEquals(request.MinPrice.Value); } if (request.MaxPrice.HasValue) { r.LessThanOrEquals(request.MaxPrice.Value); } return r; }); } if (request.Types != null && request.Types.Length > 0) { query &= q.Terms(t => t.Field(f => f.Type).Terms(request.Types)); } return query; }); // Source部分原逻辑正常,保留即可 x = x.Source(s => s.Excludes(se => { if (request.ExcludeSummary) { se = se.Field(sef => sef.Summary); } if (request.ExcludeTimestamp) { se = se.Field(sef => sef.Timestamp); } if (request.ExcludeLabels) { se = se.Field(sef => sef.Labels); } if (request.ExcludeTags) { se = se.Field(sef => sef.Tags); } return se; })); return x; });
上面的写法默认所有生效的查询条件为与逻辑(即所有条件同时满足),如果需要或逻辑,将&=替换为|=即可。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

