猫鼬如何在数组中查找对象

时间:2020-08-16 11:42:32

标签: node.js mongodb mongoose

enter image description here

我尝试了几种方法,但是没有用。如何从2个数组中查找对象。我的尝试:

Message.find({$and : [{_id : id}, {"users._id" : userID}]})

我的消息架构

const contentSchema = new Schema({
    ismy : Boolean,
    message : String
},{ timestamps: true });


const receiverSchema = new Schema({
    _id : String,
    messages : [contentSchema]
});


const messageSchema = new Schema({
    _id : String,
    users : [receiverSchema]
});

module.exports = mongoose.model('Message',messageSchema);

已退回所有文档,但我想要带有"_id": "5f38f3574644e92d0cbbc5be",的文档

[
    {
        "_id": "20860f7806d19d7a29a8addc525f73b5",
        "users": [
            {
                "messages": [
                    {
                        "_id": "5f38f3574644e92d0cbbc5be",
                        "ismy": true,
                        "message": "aaaa",
                        "createdAt": "2020-08-16T08:50:31.317Z",
                        "updatedAt": "2020-08-16T08:50:31.317Z"
                    },
                    {
                        "_id": "5f38f39d4a11553f38da0ec8",
                        "ismy": true,
                        "message": "aaaa",
                        "createdAt": "2020-08-16T08:51:41.093Z",
                        "updatedAt": "2020-08-16T08:51:41.093Z"
                    },
                    {
                        "_id": "5f38f3a84a11553f38da0eca",
                        "ismy": true,
                        "message": "aaaaDASDASDSA",
                        "createdAt": "2020-08-16T08:51:52.407Z",
                        "updatedAt": "2020-08-16T08:51:52.407Z"
                    },
                    {
                        "_id": "5f38f3f3cb7eec3ffc61c050",
                        "ismy": true,
                        "message": "aaaaDASDASDSA",
                        "createdAt": "2020-08-16T08:53:07.809Z",
                        "updatedAt": "2020-08-16T08:53:07.809Z"
                    },
                    {
                        "_id": "5f38f3ffcb7eec3ffc61c053",
                        "ismy": true,
                        "message": "hahaha",
                        "createdAt": "2020-08-16T08:53:19.781Z",
                        "updatedAt": "2020-08-16T08:53:19.781Z"
                    }
                ],
                "_id": "9471e1b040fa962df160903066e75778"
            },
            {
                "messages": [],
                "_id": "11111111111"
            }
        ],
        "__v": 4
    }
]

1 个答案:

答案 0 :(得分:1)

执行此操作的方法可能更简单,但是应该使用以下聚合管道:

const ObjectId = require('mongoose').Types.ObjectId;
const res = await Message.aggregate(Message.aggregate([
{
    "$match": {
        // set the document id here
        _id: id
    }
},
{
    "$project": {
        "filteredMessages": {
            "$filter": {
                "input": {
                    "$map": {
                        "input": "$users",
                        "as": "user",
                        "in": {
                            "messages": {
                                "$filter": {
                                    "input": "$$user.messages",
                                    "as": "msg",
                                    "cond": {
                                // need to use ObjectId here, as the messages id's won't be plain string
                                        "$eq": ["$$msg._id", ObjectId("5f38f3574644e92d0cbbc5be")]
                                    }
                                }
                            }
                        }
                    },
                },
                "as": "filteredUser",
                "cond": {
                    "$and": [
                        {"$gt": [{"$size": "$$filteredUser.messages"}, 0]}
                    ]
                }
            }
        }
    }
}
]);

我在这里正在应用$ filter和$ map-之所以需要$ map是因为内部消息数组可以由于过滤而改变,并且当消息出现时,用户数组当然不符合条件-数组已更改。