Mongoose填充API请求和Postman,返回空数组?
我创build了一个带有nodejs,mongodb / mongoose和express的api,以使CRUD请求与json数据交互,更具体地说,使用两个mongodb集合(1:datas 2:produits)。
“数据”集合绑定到“用户”模式。
“产品”集合绑定到“产品”模式。
我的问题是:
在“User”模式中,我有一个Productlist
,它将从产品集合中获取/保存产品的ID。
我的用户模式如下所示:
//Get module var mongoose = require('mongoose'); var prodSch = require('../models/productSchema'); var Schema = mongoose.Schema; //Create user shema var user = new Schema({ "UIDUser": String, "IDUser": String, "UIDACL": String, "DatasUser": { "acl_user_id": String, "prenom": String, "role": String, "nom": String, "pseudo": String, "email": String }, "Productlist" : [{ type: Schema.Types.ObjectId, ref: 'prodSch'}], "Data_Unknown": {} }, { collection : 'datas' // define the collection to use }); //Export schema module.exports = mongoose.model('userSch', user);
所以我的User
架构保存在dataschema.js
。
我有一个不同的文件productSchema.js
product
架构。
//Get module var mongoose = require('mongoose'); var Schema = mongoose.Schema; //Create product shema var Product = new Schema({ "product": String, "UIDProduct": String, "HashKey": String, "EAN13": String, "UIDReader": String, "URL": String, "readers_Label": String, "devices_Label": String, "EntryCatalis": [{ "TETITISC": String, "TEGRDIMG": String, "TEPETIMG": String, "TEREFIMG": String, "LISCEISC": String }], "URLHeader": { "Content-Length": Number, "Last-Modified": String}, "ExpireOn": String, "Data_Unknown": {} }, { collection : 'produits' // Define the collection to use }); // exports schema module.exports = mongoose.model('prodSch', Product);
我需要在用户Productlist
保存所有创build的Productlist
的ID,我需要使用填充来完成此操作。
例如:
product{name: tomato, origin: spain, id: 001} user{fname: john, lname: doe, Productlist: 001} //id of the product, saved //via populate
我有两个不同的文件来创build/初始化我的User
架构和我的Product
架构的CRUDfunction。
在这些文件中,我有所有post,get,delete,get_by_Id等等的函数,但是分成两个文件。
所以要填充Productlist
我已经定义了Schema。 dataschema.js
product
模式的types和引用:
"Productlist" : [{ type: Schema.Types.ObjectId, ref: 'prodSch'}]
然后在pipe理routeUser.js
的CRUD函数的dataschema.js
我试图在.post
函数中做一些testing来填充Productlist
。
例如:
.post(function(req, res){ var newData = new userSch(); newData.UIDUser = req.body.UIDUser; newData.IDUser = req.body.IDUser; newData.UIDACL = req.body.UIDACL; newData.DatasUser = req.body.DatasUser; newData.acl_user_id = req.body.acl_user_id; newData.prenom = req.body.prenom; newData.role = req.body.role; newData.nom = req.body.nom; newData.pseudo = req.body.pseudo; newData.email = req.body.email; newData.Data_Unknown = req.body.Data_Unknown; newData.save(function(err){ if (err) res.status(400).send(err); userSch.find().populate('Productlist').exec(function (err, story) { if (err) return handleError(err); console.log('%s', userSch.Productlist); res.json({message: "data created successfully"}); }); }); });
我也使用pipe理productSchema.js
的CRUD函数的文件routeProduct.js
来testing这个testing。
因此,我无法在我的user
架构中的Productlist中获取产品ID。 我已经search了许多关于填充的教程,但是我从来没有find正确的解决我的问题的教程。
我理解这个想法,但我不知道如何正确使用它。
你能帮我理解我的错误,以及如何正确使用我的Productlist
。
编辑:
我对我的代码做了一些改变,我可以让我的请求没有任何错误,但我的填充仍然无法正常工作。
这是我修改的行:
.post(function(req, res){ var newData = new prodSch(); newData.product = req.body.product; newData.UIDProduct = req.body.UIDProduct; newData.HashKey = req.body.HashKey; newData.EAN13 = req.body.EAN13; newData.UIDReader = req.body.UIDReader; newData.URL = req.body.URL; newData.readers_Label = req.body.readers_Label; newData.devices_Label = req.body.devices_Label; newData.EntryCatalis = req.body.EntryCatalis; newData.TETITISC = req.body.TETITISC; newData.TEGRDIMG = req.body.TEGRDIMG; newData.TEPETIMG = req.body.TEPETIMG; newData.TEREFIMG = req.body.TEREFIMG; newData.LISCEISC = req.body.LISCEISC; newData.URLHeader = req.body.URLHeader; newData['Content-Length'] = req.body['Content-Length']; newData['Last-Modified'] = req.body['Last-Modified']; newData.ExpireOn = req.body.ExpireOn; newData.Data_Unknown = req.body.Data_Unknown; newData.populate('userSch').save(function(err){ // <--- The line if (err) res.send(err); res.json({message: "data created successfully"}); }); });
使用该代码,我可以CRUD用户或产品,但它不会填充我的用户架构中的产品列表。
你必须明白.populate()
只在查询期间有用,而不是在保存/更新/创build期间有用。 所以你的第二个例子没有做任何有用的事情:
newData.populate('userSch').save(...)
为了填充用户的Productlist
条目,您首先需要一个prodSch
文档。
假设你有一个现有的用户,你想添加一个产品到他们的产品列表中。 您首先创build产品,然后保存它:
let product = new prodSch(req.body); product.save(function(err, product) { ...
然后,您要将其添加到现有用户的产品列表中,我们将通过名为userId
的variables来识别。
我们先find用户:
userSch.findById(userId, function(err, user) { ...
然后我们将产品添加到他们的产品列表中:
user.Productlist.push(product);
然后我们保存用户:
user.save(function(err, user) { ...
一切结合起来(为简洁起见,不考虑错误和存在检查,但一定要自己添加!):
let product = new prodSch(req.body); product.save(function(err, product) { userSch.findById(userId, function(err, user) { user.Productlist.push(product); user.save(function(err, user) { ...done... }); }); });
而不是findById/push/save
,你也可以使用findByIdAndUpdate
:
product.save(function(err, product) { userSch.findByIdAndUpdate(userId, { $push : { Productlist : product._id } }, { new : true // return the updated document, if you want }, function(err, user) { ...done... }); });
然后,查询用户并填充他们拥有的产品列表:
userSch.findById(userId).populate('Productlist').exec(function(err, user) { ... });
阅读并充分理解有关人口的文档是值得的: http : //mongoosejs.com/docs/populate.html