嵌套填充 ObjectId 数组

Nested populate array of ObjectId

我正在尝试 populate array of ObjectId mongoose。在该数组中,将再次需要 populate

假设我有如下 User 数据模式:-

我知道如何从 Address populate state & country,如下所示:-

Address.find()
.populate('state')
.populate('country')
.then(async address => {
    // do stuff
})
.catch(err => res.json({ err }))

可是我怎样才能populate数组ObjectId。我做了如下所示的代码:-

User.findById({ _id: userId }) // let's say I've the userId
.populate('address')
.then(async user => {
    console.log(await user)
})
.catch(err => res.json({ err }))

不幸的是,它 returns 我是这样的:-

{
    "_id": "5fabababababababababab1"
    "name": {
        "firstName": "Lalapolalaa",
        "lastName": "Newb"
    },
    "address": [
        {
            "_id": "5fcdcdcdcdcdcdcdcdc1",
            "addressID": "5fefefefefefefefefef1" // should've populate (but not working)
        }
    ],
    "__v": 0   
}

我想要得到的如下图所示:-

{
    "_id": "5fabababababababababab1"
    "name": {
        "firstName": "Lalapolalaa",
        "lastName": "Newb"
    },
    "address": [
        {
            "_id": "5fcdcdcdcdcdcdcdcdc1",
            "addressID": { // populate happens here
                "_id": "5fefefefefefefefefef1",
                "addressOne": "Lot 1, Street 12",
                "addressTwo": "SS 21",
                "postcode" : "47500",
                "city": "Subang Jaya",
                "state": { // populate happens here
                    "_id": "5fghghghghghghghghg1",
                    "name": "Selangor",
                    "__v": 0
                },
                "country": { // populate happens here
                    "_id": "5ijijijijijijijijij1",
                    "name": "Malaysia",
                    "__v": 0
                }
                "__v": 0
            }
        }
    ],
    "__v": 0   
}

我怎样才能用下面的当前代码得到它(如上所示):-

User.findById({ _id: userId }) // let's say I've the userId
.populate('address') // assuming this populate of address works
.then(async user => {
    // how to populate state & country of Address?
    // code below only return address[0] information (assumption)
    const address = await Address.findById({ _id: user.address[0].addressID._id })
    .populate('state')
    .populate('country')
    .then(address => address)
})
.catch(err => res.json({ err }))

我可以通过以下更正自己找到解决方案:-

  • models/User.js中:-
/** Dependencies */
// Mongoose
const mongoose = require('mongoose')

/** Data Schema */
// User Data Schema
const UserSchema = new mongoose.Schema({
    // User's Name
    name: {
        // User's Firstname
        firstName: { type: String, required: true, min: 4 },
        // User's Lastname
        lastName: { type: String, required: true, min: 4 }
    },
    // User's Address Array[ID]
    address: [{ type: mongoose.Schema.Types.ObjectId, ref: "Address" }] // 1st Correction
})

/** Data Schema Exports */
module.exports = mongoose.model('User', UserSchema);

然后接下来我可以直接代码如下所示(SOLUTION):-

User.findById({ _id: userId }) // let's say I've the userId
.populate('address') // assuming this populate of address works
.then(async user => {
    // create an array to hold JUST the IDs of Address available
    let addressesID = []
    // transfer all Address's ID
    for(let i = 0; i < (user.address).length; i++) {
        // push available address's ID one by one
        addressesID.push(user.address[i]._id)
    }
    // get all address info available in Address (from DB) 
    const addresses = await Address.find(
        { _id: { $in: addressesID } }
    )
    .populate('state')
    .populate('country')
    .then(address => address)
})
.then(all => console.log(all))
.catch(err => res.json({ err }))

然后 console.log()

{
    _id: '5fabababababababababab1',
    name: {
        firstName: 'Lalapolalaa',
        lastName: 'Newb'
    },
    address: { // populate happens here
        _id: '5fefefefefefefefefef1',
        addressOne: 'Lot 1, Street 12',
        addressTwo: 'SS 21',
        postcode" : '47500',
        city: 'Subang Jaya',
        state: { // populate happens here
            _id: '5fghghghghghghghghg1',
            name: 'Selangor',
            __v: 0
        },
        country: { // populate happens here
            _id: '5ijijijijijijijijij1',
            name: 'Malaysia',
            __v: 0
        },
        __v: 0
    },
    __v: 0
}