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

C# MongoDB查询:获取文档及匹配指定用户的数组元素问题

解决MongoDB查询中返回数组所有匹配元素的问题

我懂你现在的困扰啦——你想获取完整的Blends根文档,同时只保留Review数组里匹配指定用户的所有评论,但当前代码只能返回第一个匹配的评论,对吧?

问题根源

你当前使用的Review.$是MongoDB的位置操作符,它的核心作用就是仅返回数组中第一个匹配查询条件的元素,这就是为什么你只能拿到一条评论的原因。要返回所有匹配的数组元素,我们需要用更灵活的数组过滤方式。

解决方案一:使用聚合管道(推荐)

通过MongoDB的聚合管道,我们可以先筛选出符合条件的文档,再过滤数组保留所有匹配的元素,同时完整保留根文档的其他字段:

var client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("GinAndTonic");
var collection = db.GetCollection<Blends>("Blends");

var targetUsername = "你要查询的用户名";

var aggregationPipeline = new BsonDocument[]
{
    // 第一步:筛选出包含目标用户评论的Blends文档
    new BsonDocument("$match", new BsonDocument("Review.User", targetUsername)),
    // 第二步:替换Review字段为过滤后的数组,只保留目标用户的评论
    new BsonDocument("$addFields", new BsonDocument(
        "Review", new BsonDocument("$filter", new BsonDocument
        {
            {"input", "$Review"},
            {"as", "review"},
            {"cond", new BsonDocument("$eq", new BsonArray {"$$review.User", targetUsername})}
        })
    ))
};

var result = await collection.Aggregate<Blends>(aggregationPipeline).ToListAsync();

解决方案二:使用LINQ投影(更易读)

如果你习惯用LINQ语法,MongoDB驱动可以自动将LINQ的数组过滤逻辑转换成MongoDB的$filter操作符,代码更直观:

var client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("GinAndTonic");
var collection = db.GetCollection<Blends>("Blends");

var targetUsername = "你要查询的用户名";

// 先筛选出包含目标用户评论的文档
var filter = Builders<Blends>.Filter.Eq("Review.User", targetUsername);

// 构建投影:保留所有根文档字段,同时过滤Review数组
var projection = Builders<Blends>.Projection.Expression(blend => new Blends
{
    _id = blend._id,
    GinID = blend.GinID,
    TonicID = blend.TonicID,
    GarnishID = blend.GarnishID,
    GinName = blend.GinName,
    TonicName = blend.TonicName,
    GarnishName = blend.GarnishName,
    Rating = blend.Rating,
    RatingSum = blend.RatingSum,
    RatingCount = blend.RatingCount,
    Review = blend.Review.Where(review => review.User == targetUsername).ToList()
});

var result = await collection.Find(filter).Project(projection).ToListAsync();

补充说明

  • 这两种方法都要求你的MongoDB版本在3.2及以上($filter操作符从3.2开始支持),现在大部分生产环境都满足这个条件。
  • 如果你的MongoDB版本过低,只能用$unwind + $match + $group的组合方式,但这种方式代码更繁琐,性能也不如$filter,不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:29:55