Mongoose去重ISBN查询及跨集合筛选实现相关问题
背景数据结构
作者集合
[ { "_id":"asdasd2dqdfwefwe", "books":[ "ISBN2e242", "ISBNasdasdasd" ] }, { "_id":"asdasd2dqdfwefwe", "books":[ "ISBN2e242", "ISBN1111sdasd" ] } ]
图书集合
[ {"ISBN":"ISBN2e242", "title":"some book1"}, {"ISBN":"ISBN2e299", "title":"some book2"}, {"ISBN":"ISBN1111sdasd", "title":"some book3"}, {"ISBN":"ISBN2e242", "title":"some book4"}, {"ISBN":"ISBNasdasdasd", "title":"some book5"}, ]
Q1:如何使用Mongoose查询得到所有唯一ISBN的扁平化数组,预期返回结果为['ISBN2e242','ISBNasdasdasd','ISBN1111sdasd']
直接使用Mongoose聚合操作即可实现,代码如下:
const Author = require('./models/author'); // 替换为你自己的Author模型路径 const res = await Author.aggregate([ // 展开所有作者的books数组为单条记录 { $unwind: "$books" }, // 去重收集所有ISBN值 { $group: { _id: null, uniqueIsbns: { $addToSet: "$books" } } }, // 调整输出格式,去掉冗余的_id字段 { $project: { _id: 0, uniqueIsbns: 1 } } ]); // 最终目标数组:res[0].uniqueIsbns
Q2:如何获取books集合中ISBN属于Q1返回结果的所有图书记录?这两个操作是否可以合并为一条查询或聚合语句?
分两次操作的写法
先拿到Q1的唯一ISBN数组,再用$in查询图书集合即可:
const Book = require('./models/book'); // 替换为你自己的Book模型路径 const isbnList = res[0].uniqueIsbns; const matchedBooks = await Book.find({ ISBN: { $in: isbnList } });
合并为一条聚合语句的写法
可以通过$lookup关联查询一步完成,不需要两次请求数据库:
const result = await Author.aggregate([ // 展开books数组 { $unwind: "$books" }, // 去重收集所有唯一ISBN { $group: { _id: null, uniqueIsbns: { $addToSet: "$books" } } }, // 关联books集合,匹配符合条件的图书记录 { $lookup: { from: "books", // 注意填MongoDB中books集合的实际名称,一般为小写复数格式 localField: "uniqueIsbns", foreignField: "ISBN", as: "matchedBooks" } }, // 调整输出,只保留匹配到的图书记录 { $project: { _id: 0, matchedBooks: 1 } } ]); // 最终目标图书列表:result[0].matchedBooks
内容的提问来源于stack exchange,提问作者helloworld
相关产品推荐
相关产品推荐

