首页 > 解决方案 > 猫鼬如何在数组中查找对象

问题描述

在此处输入图像描述

我尝试了一些方法,但它不起作用。如何从 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
    }
]

标签: node.jsmongodbmongoose

解决方案


可能有更简单的方法可以做到这一点,但应该工作的是以下聚合管道:

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 是需要的,因为内部消息数组可以作为过滤的结果而改变,并且用户数组当然与消息数组改变时的条件不匹配.


推荐阅读