Filter data using mongoose populate

后端 未结 1 451
予麋鹿
予麋鹿 2021-01-27 02:58

I have two data structures \"database\" and \"components\"

const DatabaseSchema = mongoose.Schema({
    components: [{ type: Schema.Types.ObjectId, ref: \'Compon         


        
相关标签:
1条回答
  • 2021-01-27 03:37

    Please try this :

    As I've already suggested you can use this :

    Database.find({})
        .populate({ path: 'components', match: { name: /antr/i }, select: 'name -_id' })
        .exec((err, data) => { console.log(err); res.json(data); });
    

    Since you're seeing empty array's is because of the filter query in match which doesn't find appropriate documents in components collection w.r.t. ObjectIds in components array of database document, this is normal. May be you can filter those out in code, as you aren't looking in that way, You can use mongoDB's $lookup from aggregation framework which is equivalent to .populate() from mongoose.

    Database.aggregate(
        [{
            $lookup: {
                from: "components",
                "let": { "ids": "$components" },
                pipeline: [
                    { $match: { $expr: { $in: ['$_id', '$$ids'] } } }],
                as: "dbComponentsArray"
            }
        }, { $unwind: '$dbComponentsArray' }, { $match: { 'dbComponentsArray.name': /antr/i } },
        { $group: { _id: '$_id', dbComponentsArray: { $push: '$dbComponentsArray' }, data: { $first: '$$ROOT' } } }, { $addFields: { 'data.dbComponentsArray': '$dbComponentsArray' } },
        { $replaceRoot: { 'newRoot': '$data' } }])
    

    Sample Data in collections :

    components :

    /* 1 */
    {
        "_id" : ObjectId("5d481cd098ba991c0857959f"),
        "name" : "antracito",
        "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
        "__v" : 0
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5d481cd098ba991c0857958f"),
        "name" : "anacito",
        "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
        "__v" : 0
    }
    
    /* 3 */
    {
        "_id" : ObjectId("5d481cd098ba991c0857951f"),
        "name" : "antracito",
        "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
        "__v" : 0
    }
    
    /* 4 */
    {
        "_id" : ObjectId("5d481cd098ba991c0857952f"),
        "name" : "anacito",
        "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
        "__v" : 0
    }
    

    database :

    /* 1 */
    {
        "_id" : ObjectId("5d4979d52a17d10a6c8de81b"),
        "components" : [ 
            ObjectId("5d481cd098ba991c0857951f"), 
            ObjectId("5d481cd098ba991c0857952f"), 
            ObjectId("5d481cd098ba991c0857953f"), 
            ObjectId("5d481cd098ba991c0857959f")
        ]
    }
    

    Output :

    /* 1 */
    {
        "_id" : ObjectId("5d4979d52a17d10a6c8de81b"),
        "components" : [ 
            ObjectId("5d481cd098ba991c0857951f"), 
            ObjectId("5d481cd098ba991c0857952f"), 
            ObjectId("5d481cd098ba991c0857953f"), 
            ObjectId("5d481cd098ba991c0857959f")
        ],
        "dbComponentsArray" : [ 
            {
                "_id" : ObjectId("5d481cd098ba991c0857959f"),
                "name" : "antracito",
                "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
                "__v" : 0
            }, 
            {
                "_id" : ObjectId("5d481cd098ba991c0857951f"),
                "name" : "antracito",
                "updatedAt" : ISODate("2019-08-05T12:10:56.777Z"),
                "__v" : 0
            }
        ]
    }
    
    0 讨论(0)
提交回复
热议问题