使用Mongoose查询MongoDB中key值唯一的文档
用Mongoose查找key值唯一的文档
假设我们有一个名为MyDoc的Schema,包含key字段,现有文档如下:
[ { "key": 1 }, { "key": 2 }, { "key": 2 }, { "key": 3 }, { "key": 3 }, { "key": 3 }, { "key": 4 } ]
我们需要找出key值唯一的文档——也就是那些key只出现过一次的记录,示例中就是key为1和4的两条文档。
方法一:全程使用聚合管道(单次数据库操作)
通过MongoDB的聚合管道,可一次性完成统计、筛选和关联查询:
MyDoc.aggregate([ // 按key分组,统计每个key的出现次数,同时收集对应文档ID { $group: { _id: "$key", count: { $sum: 1 }, docIds: { $push: "$_id" } } }, // 筛选出仅出现一次的key分组 { $match: { count: 1 } }, // 展开文档ID数组(因为count=1,数组仅含一个ID) { $unwind: "$docIds" }, // 关联原集合获取完整文档数据 { $lookup: { from: "mydocs", // 注意这里是集合实际名称,默认是Schema名小写复数 localField: "docIds", foreignField: "_id", as: "document" } }, // 展开文档数组 { $unwind: "$document" }, // 保留需要的字段,移除中间生成的冗余字段 { $project: { _id: "$document._id", key: "$document.key" // 若Schema有其他字段,在此处添加即可 } } ]) .then(uniqueDocs => { console.log(uniqueDocs); // 输出key为1和4的文档 }) .catch(err => { console.error(err); });
方法二:分两次查询(代码更简洁)
先统计出所有仅出现一次的key,再用这些key去查询原文档:
// 第一步:统计每个key的出现次数,筛选出唯一的key MyDoc.aggregate([ { $group: { _id: "$key", count: { $sum: 1 } } }, { $match: { count: 1 } } ]) .then(uniqueKeyStats => { // 提取出所有唯一的key值 const targetKeys = uniqueKeyStats.map(item => item._id); // 第二步:查询原文档中key属于目标数组的记录 return MyDoc.find({ key: { $in: targetKeys } }); }) .then(uniqueDocs => { console.log(uniqueDocs); // 输出目标文档 }) .catch(err => { console.error(err); });
注意事项
- 使用
$lookup时,from参数要填写集合的实际名称,Mongoose默认会将Schema名称转为小写复数形式(比如MyDoc对应mydocs),如果自定义过集合名称,要改成对应的名称。 - 数据量不大时,两种方法都可以;数据量较大时,推荐使用聚合管道的方式,减少一次数据库请求。
内容的提问来源于stack exchange,提问作者Dashiell Rose Bark-Huss
相关产品推荐
相关产品推荐

