You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何构建同时支持与或运算符的MongoDB动态查询

问题核心原因

你的代码有三个核心错误导致逻辑不符合预期:

  1. 拼接同key多值的或条件时,误用了代表逻辑与的&=运算符,才会生成AndFilterDefinition而非预期的OrFilterDefinition
  2. orFilters变量定义在遍历过滤条件的循环外层,多个多值过滤条件会互相污染
  3. 单值条件下直接将数组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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:42:04