C#如何构建同时支持与或运算符的MongoDB动态查询
问题核心原因
你的代码有三个核心错误导致逻辑不符合预期:
- 拼接同key多值的或条件时,误用了代表逻辑与的
&=运算符,才会生成AndFilterDefinition而非预期的OrFilterDefinition orFilters变量定义在遍历过滤条件的循环外层,多个多值过滤条件会互相污染- 单值条件下直接将数组
filter.Value传给Eq方法,语义错误,应该取数组的第一个元素
修复后的实现方案
方案1:直接修正原有逻辑
var builder = Builders<ReportDocument>.Filter; var dynamicQuery = builder.Empty; foreach (var filter in request.Filters) { FilterDefinition<ReportDocument> currentFilter = builder.Empty; // 单个key的多个值是逻辑或关系 for (int i = 0; i < filter.Value.Length; i++) { if (i == 0) { currentFilter = builder.Eq(filter.Key, filter.Value[i]); } else { // 用逻辑或运算符拼接同key的多个值 currentFilter |= builder.Eq(filter.Key, filter.Value[i]); } } // 不同key之间是逻辑与关系 dynamicQuery &= currentFilter; } return await _reportsCollection.Find(dynamicQuery).ToListAsync();
方案2:更简洁的In方法实现(推荐)
同个字段匹配多个值的或逻辑,本质就是MongoDB的$in运算符语义,用驱动封装的In方法可以大幅简化代码:
var builder = Builders<ReportDocument>.Filter; var dynamicQuery = builder.Empty; foreach (var filter in request.Filters) { // 直接用In方法实现同key多值的或匹配 dynamicQuery &= builder.In(filter.Key, filter.Value); } return await _reportsCollection.Find(dynamicQuery).ToListAsync();
以上两种方案生成的过滤条件,和你给出的硬编码查询效果完全一致。
注:如果你需要匹配
placement_type的首字母大写格式,可以在传入条件前先对filter.Value的元素做大小写转换处理。
内容的提问来源于stack exchange,提问作者Miguel Vale
相关产品推荐
相关产品推荐

