【问题标题】:Mongoose Populate with API request and Postman, return empty array?Mongoose 使用 API 请求和 Postman 填充,返回空数组?
【发布时间】:2017-10-24 12:29:15
【问题描述】:

我用 nodejs、mongodb/mongoose 和 express 创建了一个 api,以发出 CRUD 请求以与 json 数据交互,更具体地说,使用两个 mongodb 集合(1:数据 2:produits)。

“数据”集合绑定到“用户”模式。
“产品”集合绑定到“产品”模式。

我的问题是:
在“用户”模式中,我有一个地方 Productlist,它将从 produits 集合中获取/保存产品的 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);

我需要在 User Productlist 中保存创建的所有产品的 ID,我需要使用填充来执行此操作。

例如:

product{name: tomato, origin: spain, id: 001}

user{fname: john, lname: doe, Productlist: 001} //id of the product, saved 
                                                //via populate 

我有两个不同的文件来创建/初始化我的User 架构和我的Product 架构的 CRUD 函数。

在这些文件中,我拥有发布、获取、删除、get_by_Id 等的所有功能... 但分成两个文件。

所以要填充Productlist,我已经定义了架构。 dataschema.jsproduct 模式的类型和引用:

 "Productlist" : [{ type: Schema.Types.ObjectId, ref: 'prodSch'}]

然后在为dataschema.js 管理CRUD 函数的routeUser.js 中,我尝试在.post 函数中进行一些测试以填充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"});
            });
    });
});

我还使用文件 routeProduct.js 进行了测试,该文件管理 productSchema.js 的 CRUD 功能。

因此,我无法在 user 架构中的 Productlist 中获取产品 ID。 我搜索了很多关于填充的教程,但我从来没有找到适合我的问题的教程。

我理解这个想法,但我不知道如何正确使用它。

您能帮我理解我的错误是什么,以及如何正确使用我的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,但它不会在我的用户架构中填充我的产品列表。

【问题讨论】:

  • 愿你edit你的问题基于在线拼写检查器。我知道这可能很烦人,您已经花了一些时间来创建这个问题。但它很难阅读.. 真的很难!
  • 你能说得更具体些吗?抱歉,我不完全理解你的问题,你想让我改变一切吗?还是只是问题的标题?
  • @DragandDrop 我希望我的编辑是正确的,如果有问题请再次告诉我,谢谢。
  • @DragandDrop 谢谢你的修改我很感激谢谢

标签: javascript node.js api mongoose-populate


【解决方案1】:

您必须了解.populate() 仅在查询期间有用,在保存/更新/创建期间无效。所以你的第二个例子没有做任何有用的事情:

newData.populate('userSch').save(...)

为了填充用户的Productlist 条目,您首先需要一个prodSch 文档。

假设您有一个现有用户,并且您想将产品添加到他们的产品列表中。您首先创建产品并保存它:

let product = new prodSch(req.body); 

product.save(function(err, product) { ...

然后,您想将其添加到现有用户的产品列表中,我们将通过一个名为 userId 的变量来识别它。

我们首先找到用户:

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

【讨论】:

  • 您好,感谢您的回复,以及您对使用填充的帮助,我尝试将您的示例添加到我的代码中,如果出现问题,我可以@您吗?我想投票给你,但我没有能力这样做,所以+10 非常感谢我试试这个。谢谢
  • @amalrik 当然,如果您遇到问题可以 ping 我 :)
猜你喜欢
  • 2016-12-04
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 2020-11-11
相关资源
最近更新 更多