如何不使用MongoDB Aggregate,基于resId获取唯一文档以适配分页?
不使用Aggregate实现MongoDB基于resId的文档去重并支持分页
直接通过find()无法在MongoDB服务端完成基于resId的完整文档去重,因为find()本身没有针对多字段文档的去重能力——distinct()方法只能返回单个字段的去重值,没法返回整份文档。不过可以通过以下两种方式绕开aggregate实现需求:
方案一:服务端分页后客户端去重
先用find()结合正则过滤、分页参数拿到数据,再在客户端对结果按resId去重。这种方式简单直接,但要注意:如果当前分页的结果里包含重复的resId,去重后当前页的实际数据量会少于分页设置的条数,需要前端做兼容处理。
示例代码(Node.js环境):
// 服务端查询:正则过滤+分页 const pageSize = 10; const pageNum = 1; const query = { networkID: /myNetwork/ }; // 示例正则条件 const docs = await db.collection('yourCollection').find(query) .skip((pageNum - 1) * pageSize) .limit(pageSize) .toArray(); // 客户端去重:保留每个resId对应的第一条文档 const uniqueDocs = []; const seenResIds = new Set(); for (const doc of docs) { if (!seenResIds.has(doc.resId)) { seenResIds.add(doc.resId); uniqueDocs.push(doc); } }
方案二:预处理去重集合(推荐)
维护一个专门的去重集合,每当原集合插入或更新文档时,保证该集合中每个resId仅保留一条文档(比如保留最早插入的、或最新更新的)。之后直接在这个去重集合上用find()+正则+分页,完全符合你的全局分页需求。
示例代码(MongoDB Shell):
// 原集合插入/更新时,同步更新去重集合(保留每个resId的第一条文档) db.yourCollection.insertOne({ "networkID": "myNetwork1", "pointID": "point001", "param": "param1", "resId": "123" }); // 同步到去重集合:upsert=true,若resId不存在则插入,存在则不更新(保留第一条) db.uniqueCollection.updateOne( { resId: "123" }, { $setOnInsert: { networkID: "myNetwork1", pointID: "point001", param: "param1", resId: "123" } }, { upsert: true } ); // 查询去重集合:正则+分页 db.uniqueCollection.find({ networkID: /myNetwork/ }) .skip(0) .limit(10) .toArray();
如果需要保留每个resId的最新文档,只需把$setOnInsert换成$set即可,这样每次更新时会覆盖旧文档,始终保留最新的一条。
内容的提问来源于stack exchange,提问作者Mohit Soni
相关产品推荐
相关产品推荐

