从id填充Mongoose对象到新字段

时间:2019-01-29 20:21:06

标签: node.js express mongoose mongoose-populate

我当时正与猫鼬一起使用ID字段及其各自的文档填充到新字段。我的问题是假设我的购物车模型是-

let CartSchema = new mongoose.Schema({
    userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    productIds: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Product'
        }
    ]
});

我想填充所用的产品

Cart.find({}).populate("products").exec(function (err, cart) {
    console.log(cart)
}

但是这会使用相同的字段名称productIds填充文档,我想将这些字段填充到名为“ products”的新字段名称中,所以我尝试了此操作

let CartSchema = new mongoose.Schema({
        userId: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        },
        productIds: [
            {
                type: String
            }
        ]
    }, { toJSON: { virtuals: true } });

CartSchema.virtual('products', {
    ref: 'Product',
    localField: 'productIds',
    foreignField: '_id',
});

Cart.find({}).populate("products").exec(function (err, cart) {
    console.log(cart)
}

但是返回了一个名为products的空数组。因此,如何将productIds数组填充到具有各自文档数组的新字段名称产品中。

谢谢。

3 个答案:

答案 0 :(得分:2)

有一种方法可以做到这一点-称为虚拟(Virtuals)(请参阅docs)。 这个想法是创建一个“虚拟属性”,它实际上并没有保存到数据库中,而是作为一个计算属性。按照相关github问题上的示例provided by qinshenxue

// declare your ID field as a regular string
var countrySchema = new mongoose.Schema({
    capitalId: {type:String}
});

// create a virtual field which links between the field you've just declared 
// and the related collection. 
// localField is the name of the connecting field, 
// foreign field is a corresponding field in the connected collection
// justOne says that it'll populate a single connected object, 
// set it to false if you need to get an array
countrySchema.virtual('capital',{
    ref: 'City',
    localField: 'capitalId',
    foreignField: '_id',
    justOne: true
});

// tell Mongoose to retreive the virtual fields
countrySchema.set('toObject', { virtuals: true });
countrySchema.set('toJSON', { virtuals: true });

// now you can populate your virtual field like it actually exists
// the following will return a Country object in the 'capital' field
Country.find().populate('capital') 

答案 1 :(得分:0)

在使用猫鼬方面,做您想做的事情在技术上违反了约定和标准。您只需将“ productIds”字段重命名为“ products”即可使事情变得简单:

如果您仔细考虑,这还是有道理的,产品数组可以是产品ID值的数组,也可以是实际文档,如果有,则每个文档上都带有“ _id”字段你需要它。不必仅使用id值就用单独的属性来膨胀JSON,您已经拥有了它们!

这往往总能解决,因为您总是知道选择填充属性的时间以及何时不填充属性。

期望文档时获得ID或期望ID时获得文档的可能性很小。

答案 2 :(得分:0)

该方法是正确的,您应该在产品字段中看到已填充的数据。确保您拥有正确的数据和模型n