NodeJS $and运算符在findOne mongoose中不起作用

pqwbnv8z  于 2023-05-28  发布在  Node.js
关注(0)|答案(1)|浏览(152)

BorrowBookSchema

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

    }]
})

只返回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")
    }
  ]
wi3ka0sx

wi3ka0sx1#

您正在通过子文档字段的值(status)过滤bookdetails子文档,而不是过滤borrow_book文档。在borrow_book集合上使用运算符($and)只会影响其查询结果,而不会影响子文档。
查询选择borrow_book集合中的所有文档,其中:

  • member_id字段值等于books[0].member_id
  • bookdetails数组至少有一个嵌入文档,其中包含值为false的字段status

聚合管道可以做到这一点。
例如(“mongoose”:“^7.1.1”

import mongoose from "mongoose";
import util from 'util';
import { config } from '../../config';

mongoose.set('debug', true);

const borrowBookSchema = new mongoose.Schema({
  member_id: {
    type: String,
    required: true,
  },
  bookdetails: [{
    bookid: String,
    status: Boolean
  }]
});
const BorrowBook = mongoose.model('borrow_book', borrowBookSchema);

(async function main() {
  try {
    await mongoose.connect(config.MONGODB_URI);

    // seed
    const books = await BorrowBook.create([
      {
        member_id: new mongoose.Types.ObjectId(), bookdetails: [
          { bookid: new mongoose.Types.ObjectId(), status: false },
          { bookid: new mongoose.Types.ObjectId(), status: false },
          { bookid: new mongoose.Types.ObjectId(), status: true }]
      },
      { member_id: new mongoose.Types.ObjectId(), bookdetails: [] }
    ])

    // option 1
    let response = await BorrowBook
      .aggregate()
      .match({ member_id: books[0].member_id })
      .unwind('$bookdetails')
      .match({ 'bookdetails.status': { $eq: false } })
      .group({
        _id: '$_id',
        member_id: { '$first': '$member_id' },
        bookdetails: {
          $push: {
            bookid: '$bookdetails.bookid',
            status: '$bookdetails.status',
            _id: '$bookdetails._id'
          }
        }
      })
      .exec();

    console.log(util.inspect(response, false, null))

   

  } catch (error) {
    console.error(error);
  } finally {
    await Promise.all(['borrow_books'].map(c => mongoose.connection.dropCollection(c)))
    await mongoose.connection.close()
  }
})();

选项二。

const response1 = await BorrowBook
  .aggregate()
  .match({ member_id: books[0].member_id })
  .project({
    member_id: 1,
    bookdetails: {
      $filter: {
        input: '$bookdetails',
        as: 'item',
        cond: { $eq: ['$$item.status', false] }
      }
    }
  })
  .exec()

输出:

[
  {
    _id: new ObjectId("646f51ef10de7b15bd59d23e"),
    member_id: '646f51ef10de7b15bd59d239',
    bookdetails: [
      {
        bookid: '646f51ef10de7b15bd59d23a',
        status: false,
        _id: new ObjectId("646f51ef10de7b15bd59d23f")
      },
      {
        bookid: '646f51ef10de7b15bd59d23b',
        status: false,
        _id: new ObjectId("646f51ef10de7b15bd59d240")
      }
    ]
  }
]

相关问题