使用 find 查询嵌套对象在 mongoose 中不起作用 (MongoDB)

Querying nested objects using find not working in mongoose (MongoDB)

我正在尝试获取具有 isDrafttrue[= 的对象39=],但我也得到了具有 isDraft 的对象假。我只需要具有 isDrafttrue 的对象。我已经尝试了所有可能的方法,但无法为此找到解决方案。谁能帮我解决这个问题?

下面是架构、查询和响应。

架构

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const Contract = new Schema({
    name: {
        type: String,
        unqiue: true,
        required: true
    },
    version: [
        {
            no: {
                type: Number,
                required: true
            },
            sections: [
                {
                    sectionName: {
                        type: String,
                        required: true
                    },
                    clause: [{
                        description: {
                            type: String,
                            required: true
                        },
                    }]
                }
            ],
            approvedBy: [
                {
                    user: {
                        type: Schema.Types.ObjectId,
                        ref: 'user'
                    },
                }
            ],
            acceptedBy: [
                {
                    name: {
                        type: String,
                    },
                    eamil: {
                        type: String,
                    },
                }
            ],
            isDraft: {
                type: Boolean,
                required: true
            },
            date: {
                type: Date,
                default: Date.now
            }
        }
    ],
    createdBy: {
        type: Schema.Types.ObjectId,
        ref: 'user',
        required: true
    },

});

module.exports = mongoose.model('contract', Contract);

查询

query = {
            $and: [
                { createdBy: clientAdminDetails._id },
                { "version.isDraft": true }
            ],
        };
        await Contract
            .find(query)
            .skip(req.body.noOfItems * (req.body.pageNumber - 1))
            .limit(req.body.noOfItems)
            .exec((err, contract) => {
                if (err) {
                    return res.json(err);
                }
                Contract.countDocuments(query).exec((count_error, count) => {
                    if (err) {
                        return res.json(count_error);
                    }
                    return res.json({
                        total: count,
                        page: req.body.pageNumber,
                        pageSize: contract.length,
                        contracts: contract
                    });
                });
            });

回应

{
    "total": 1,
    "page": 1,
    "pageSize": 1,
    "contracts": [
        {
            "_id": "61449469775..",
            "name": "Octavia Blankenship",
            "version": [
                {
                    "_id": "614496593cc..",
                    "sections": [
                        {
                            "_id": "61449469775..",
                            "sectionName": "Est dolore dolorem n Updated `1323",
                            "clause": [
                                {
                                    "_id": "614494697..",
                                    "description": "Numquam nostrud et a"
                                }
                            ]
                        }
                    ],
                    "isDraft": false,
                    "no": 1,
                    "approvedBy": [],
                    "acceptedBy": [],
                    "date": "2021-09-17T13:21:29.509Z"
                },
                {
                    "_id": "614496122904ee4e046fbee8",
                    "sections": [
                        {
                            "_id": "6144955a8c0061025499606f",
                            "sectionName": "Praesentium suscipit",
                            "clause": [
                                {
                                    "_id": "6144955a8c00610254996070",
                                    "description": "Velit aperiam ut vel"
                                }
                            ]
                        }
                    ],
                    "isDraft": true,
                    "no": 2,
                    "approvedBy": [],
                    "acceptedBy": [],
                    "date": "2021-09-17T13:20:18.128Z"
                }
            ],
            "createdBy": "614367e980b29e6c...",
            "__v": 0
        }
    ]
}

这就是为什么使用您的查询时您会告诉 mongo“给我一份文档,其中 createdBy 是所需的 ID,而 version.isdraft 是 true” 因此,由于 DOCUMENT 包含这两个值, 被返回,即使现有 false 进入数组。

解决这个问题的方法有很多。

第一个是使用 $elemMatch 投影 (docs here)。但是使用这种方式只返回第一个元素,所以我认为你更喜欢其他方式。

因此您可以使用 $filter 的聚合查询,如下所示:

  • 首先 $match 按您想要的值(如在您的查询中)。
  • 然后按 isDraft = true.
  • 中的值覆盖 version 数组过滤
db.collection.aggregate([
  {
    "$match": {
      "createdBy": "",
      "version.isDraft": true
    }
  },
  {
    "$set": {
      "version": {
        "$filter": {
          "input": "$version",
          "as": "v",
          "cond": {
            "$eq": [
              "$$v.isDraft",
              true
            ]
          }
        }
      }
    }
  }
])

示例here