MongoDB技术问题:$unwind后单条匹配及按usr.id统计文档数
解决MongoDB文档的查询与统计需求
先把你的原始MongoDB文档列出来,方便参考:
[ { _id : 1, nm : 1, usr:[ {id : 1, ty : 'team'}, {id : 2, em : 'a'}, {id : 3, em : 'b'} ] }, { _id : 2, nm : 2, usr:[ {id : 2, em : 'a'}, {id : 3, em : 'b'} ] }, { _id : 3, nm : 3, usr:[ {id : 1, ty : 'team'}, {id : 3, em : 'b'} ] }, { _id : 4, nm : 4, usr:[ {id : 3, em : 'b'} ] } ]
需求1:$unwind后仅匹配单条记录
要实现这个需求,我们可以通过聚合管道先拆分usr数组,再筛选目标记录,最后限制只返回一条。比如如果我们想匹配usr.id=1的单条记录,管道如下:
db.collection.aggregate([ // 拆分usr数组,每个数组元素生成一个独立文档 { $unwind: "$usr" }, // 筛选出usr.id等于1的记录 { $match: { "usr.id": 1 } }, // 只返回第一条匹配结果 { $limit: 1 } ])
执行后会得到一条拆分后的文档:{ _id: 1, nm: 1, usr: { id: 1, ty: 'team' } }。如果需要匹配其他条件,只需要修改$match里的规则即可。
需求2:按指定数组统计符合条件的文档数
这里的核心是统计文档的数量(不是拆分后的元素数量),所以不能直接用$unwind后计数,否则会重复统计同一个文档。我们需要先筛选出usr数组中包含目标id的文档,再统计数量。
示例1:查询条件userAndTeam = [1, 2]
要统计所有usr.id为1或2的文档,管道如下:
db.collection.aggregate([ // 匹配usr数组中存在id在[1,2]里的文档 { $match: { "usr.id": { $in: [1, 2] } } }, // 统计符合条件的文档总数 { $count: "total_matching_docs" } ])
执行后会返回{ total_matching_docs: 3 },对应原始文档中的_id=1、2、3这三个符合条件的文档。
示例2:查询条件userAndTeam4 = [1, 4]
同理,把$in的参数换成[1,4]即可:
db.collection.aggregate([ { $match: { "usr.id": { $in: [1, 4] } } }, { $count: "total_matching_docs" } ])
执行后返回{ total_matching_docs: 2 },对应_id=1、3这两个文档。
如果是在代码中动态传入查询数组,比如Node.js环境,你可以这样写:
// 动态定义查询数组 const userAndTeam = [1, 2]; // 执行聚合查询 const countResult = await db.collection.aggregate([ { $match: { "usr.id": { $in: userAndTeam } } }, { $count: "total" } ]).next(); // 输出统计结果 console.log(`符合条件的文档数:${countResult.total}`);
内容的提问来源于stack exchange,提问作者Shrabanee
相关产品推荐
相关产品推荐

