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

MongoDB C#驱动:查询UserThemes中值大于100的用户

问题:筛选UserThemes中存在值大于100的用户

需求说明

我有一个UserInfo集合,其中包含UserThemes字段(类型为BsonDocument),需要筛选出UserThemes中至少有一个值大于100的用户。

C#实体定义

public record UserInfo:BaseDocument
{
    public string UserName { get; set; }
    public BsonDocument UserThemes { get; init; } = new BsonDocument();
}

示例存储数据

{
    "_id" : ObjectId("62f8fe33127584b3e027060e"),
    "UserId" : "7BCBCC2DA9624BCB8191AC2DBDC5CA71",
    "UserName" : "kaveh",
    "UserThemes" : {
        "football" : 10,
        "basketball" : 110,
        "volleyball" : 90,
        "tennis" : 50,
        "golf" : 25
    }
}

失败的尝试代码

var docs = await _context.UserInfos.Aggregate()
          .Match(
                new BsonDocument() {
                   { "$expr", new BsonDocument() {
                      { "$and", new BsonArray() {
                         new BsonDocument(){{ "$gt", new BsonArray() { "$UserThemes.value", BsonValue.Create(100) } } },
                        }
                      }
                    }
                  }
                })
          .As<UserInfo>()
          .ToListAsync();

问题分析

之前的写法错误在于$UserThemes.value的引用方式不成立——UserThemes是嵌套文档而非数组,无法直接通过.value提取所有值。必须先将文档的键值对转换为数组,再判断其中是否存在满足条件的元素。

正确解决方案

方案一:聚合表达式实现(推荐)

通过$objectToArray把UserThemes转为键值对数组,再用$filter筛选出值大于100的元素,最后判断筛选结果的长度是否大于0:

var docs = await _context.UserInfos.Aggregate()
    .Match(new BsonDocument
    {
        { "$expr", new BsonDocument
            {
                { "$gt", new BsonArray
                    {
                        new BsonDocument
                        {
                            { "$size", new BsonDocument
                                {
                                    { "$filter", new BsonDocument
                                        {
                                            { "input", new BsonDocument("$objectToArray", "$UserThemes") },
                                            { "cond", new BsonDocument("$gt", new BsonArray { "$$this.v", 100 }) }
                                        }
                                    }
                                }
                            },
                            0
                        }
                    }
                }
            }
        }
    })
    .As<UserInfo>()
    .ToListAsync();

方案二:简化聚合写法

用$anyElementTrue结合$map遍历数组,直接判断是否存在满足条件的元素:

var docs = await _context.UserInfos.Aggregate()
    .Match(new BsonDocument
    {
        { "$expr", new BsonDocument
            {
                { "$anyElementTrue", new BsonDocument
                    {
                        { "$map", new BsonDocument
                            {
                                { "input", new BsonDocument("$objectToArray", "$UserThemes") },
                                { "in", new BsonDocument("$gt", new BsonArray { "$$this.v", 100 }) }
                            }
                        }
                    }
                }
            }
        }
    })
    .As<UserInfo>()
    .ToListAsync();

方案三:LINQ表达式写法(更符合C#习惯)

如果习惯用LINQ,新版本MongoDB Driver(2.x及以上)支持直接解析LINQ表达式:

var docs = await _context.UserInfos.Aggregate()
    .Match(u => u.UserThemes.Values.Any(v => v.AsInt32 > 100))
    .As<UserInfo>()
    .ToListAsync();

内容的提问来源于stack exchange,提问作者Kaveh Naseri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:57:16