如何在猫鼬的不同模型中填充子架构

问题描述 投票:0回答:1

我想填充一个模型,该模型具有文档的 ObjectId,该文档作为另一个模型上的子架构存在

子架构

var addressSchema = new Schema({
    address: String,
    phoneNumber: Number,
    name: String,
    pincode: Number,
    augmontAddressId: String,
});

主架构 - 地址是一个数组,可以有多个地址,每个对象都有自己的 objecId,我想引用

var userSchema = new Schema(
    {
      name: String,
        address: [addressSchema],
    },
    {
        timestamps: true,
    }
);

引用主模式的账本模式

var ledgerSchema = new Schema(
    {
        txnId: String,
        paymentId: String,
        addressId:{
            type: mongoose.Schema.Types.ObjectId,
            ref: "User",
        },
    },
    {
        timestamps: true,
    }
);

我试过了

LedgerSchema.findById().populate("addressId").then(res=>{
    console.log(res);
})

但它没有填充addressId而是发送空值

{
  _id: new ObjectId("650c49a20483f1ec8eb7aecd"),        
  addressId: null,
  createdAt: 2023-09-21T13:48:18.667Z,
  updatedAt: 2023-09-21T13:48:18.667Z,
  __v: 0
}

我还尝试将 ledgerSchema 中的 ref 设置为“User.address” 但它给出了一个错误

MissingSchemaError: Schema hasn't been registered for model "User.Address".
mongodb mongoose mongodb-query mongoose-schema mongoose-populate
1个回答
0
投票

哦,如果你能做

User.address
来参考事物,那就太好了。不幸的是,由于您设置子文档的方式,无法使用
populate
来完成此操作。在您的
userSchema
中,每个
address
本质上都是一个子文档,它“嵌入”在顶级文档中。相反,在您的 ledgerSchema 中,每个
addressId
都是一个
引用
文档,并且是单独的顶级文档。 我的建议是更改您的

userSchema

,以便每个

address
都是一个
引用
文档,但这将在您的数据库中创建另一个集合(addresses)。您需要它来做参考。
如果出于某种原因您无法修改架构并且需要将每个 

address

保留为

embedded
子文档,那么您可以使用 aggregate 实现所需的结果。这不是一个微不足道的任务,它并不漂亮,但它确实有效: const ledger = await ledgerModel.aggregate([ { $match: { _id: new mongoose.Types.ObjectId(id) } }, //< Your ledger _id { $lookup: //< Do a lookup to match addressId with userSchema.address._id { from: "users", localField: "addressId", foreignField: "address._id", as: "address_details" //< This creates a new array } }, { $unwind: '$address_details'}, //< Now you need to unwind the new array { $unwind: '$address_details.address'}, //< And unwind each address { $project: //< This stage only outputs the original ledger properties { txnId: 1, paymentId: 1, address_details: 1, compare_address_ids: { $cmp: [ "$addressId", "$address_details.address._id" ] }, //^ Compare addressId against ones done via lookup to find a match } }, { $match: { compare_address_ids: 0 //< 0 means they matched } }, { $project: //< Now get rid of these two made up properties from the output { compare_address_ids: 0, 'address_details.name': 0, } } ]);

© www.soinside.com 2019 - 2024. All rights reserved.