Mongoose findOne中$and查询失效,如何仅返回status:false的嵌套文档?
问题描述
我定义了如下Mongoose Schema:
const borrowBookSchema = new mongoose.Schema({ member_id : { type : String, required: true, }, member_name : { type : String, required : true }, bookdetails : [{ bookid : String, bookname : String, todaydate : String, returndate : String, status : Boolean }] })
我希望查询仅返回bookdetails数组中status: false的元素,但使用以下代码查询时,结果同时返回了status: true的元素:
const returnBorrowBook = (req,res) => { const {memberid} = req.body let response = await BorrowBook.findOne({$and : [{member_id : memberid} ,{"bookdetails.status" : false}]}) console.log(response) }
返回结果示例:
bookdetails: [ { bookid: '63f5d00a0effd7323ac20bea', bookname: 'Atomic Habits', todaydate: '03/03/2023', returndate: '03/03/2023', status: true, _id: new ObjectId("64016a278023cdb8a881a35a") }, { bookid: '63f5d00a0effd7323ac20bea', bookname: 'Atomic Habits', todaydate: '01/03/2023', returndate: null, status: false, _id: new ObjectId("64016b365203f7c11528392e") } ]
原因分析
原查询中的{"bookdetails.status": false}仅用于筛选文档(即找到包含至少一个status: false的bookdetails项的文档),而非过滤数组内的元素。因此返回的是完整文档,包含所有bookdetails元素。
解决方案
方法1:使用聚合管道(Aggregation Pipeline)
通过$match筛选目标文档,再用$project配合$filter过滤数组元素:
const returnBorrowBook = async (req, res) => { const { memberid } = req.body; const [result] = await BorrowBook.aggregate([ // 筛选符合条件的文档 { $match: { member_id: memberid, "bookdetails.status": false } }, // 过滤bookdetails数组,仅保留status为false的元素 { $project: { member_id: 1, member_name: 1, bookdetails: { $filter: { input: "$bookdetails", cond: { $eq: ["$$this.status", false] } } } } } ]); console.log(result); res.send(result || null); };
方法2:使用findOne配合投影过滤
直接在findOne的投影参数中使用$filter:
const returnBorrowBook = async (req, res) => { const { memberid } = req.body; const result = await BorrowBook.findOne( { member_id: memberid, "bookdetails.status": false }, { member_id: 1, member_name: 1, bookdetails: { $filter: { input: "$bookdetails", cond: { $eq: ["$$this.status", false] } } } } ); console.log(result); res.send(result); };
额外提示
原查询中的$and是多余的,MongoDB查询条件默认是逻辑与关系,可简化为{ member_id: memberid, "bookdetails.status": false }。
内容的提问来源于stack exchange,提问作者safwanpaloli
相关产品推荐
相关产品推荐

