【问题标题】:mongoose db returning data from two documentsmongoose db 从两个文档返回数据
【发布时间】:2014-07-15 23:13:45
【问题描述】:

我正在创建我的第一个猫鼬数据库应用程序。我正在尝试编写一个快速 API 调用,它返回一个包含来自两个文档的数据的对象。每当我调用 /data 路由时,我都会得到一个空数组。我添加了两条 console.log 行,输出为:

test2
test1

我可以做些什么来让 forEach 在返回结果之前完成?

代码如下:

router.route('/data')
//get all data
.get(function(req, res) {
    var results = [];
    Attendee.find(function(err, attendees) {
        if (err) {res.send(err);}
        else {
            attendees.forEach(function(attendee) {

                Message.find({userID: attendee._id}, function(err,messages){
                    results.push({
                        attendee: attendee,
                        messages: messages
                    });
                });
                console.log("test1");
                console.log(results);
            });
            console.log("test2");
            res.json(results);
        }
    });
});

这是我想要得到的结果

[ { attendee: 
 { _id: 53c060e7fb90e3d709d6bdae,
   fullName: ‘joe smith,
   phoneNumber: '+555’,
   __v: 0 },
messages: 
 [ { _id: 53c06887fb1d24fb095fd365,
     phoneNumber: '+555',
     body: ‘test’,
     userID: '53c060e7fb90e3d709d6bdae',
     sid: 'SMa86f2914986d4b04067d7f054da205a5',
     __v: 0 },
   { _id: 53c41cf3d068393d17dc0dbf,
     phoneNumber: '+555',
     body: ‘test’,
     userID: '53c060e7fb90e3d709d6bdae',
     sid: 'SM4f6c64ca7b39e6caee9859e761a2850d',
     __v: 0 },
   { _id: 53c421e16371e54f171751cf,
     phoneNumber: '+555',
     body: ‘test’,
     userID: '53c060e7fb90e3d709d6bdae',
     sid: 'SM1097eae33e4f53cdcdad32651c016437',
     __v: 0 },
   { _id: 53c421e16371e54f171751d0,
     phoneNumber: '+555',
     body: ‘test’,
     userID: '53c060e7fb90e3d709d6bdae',
     sid: 'SM5a452e51c995d7ad6ad8f7b85cec80b0',
     __v: 0 } ] } ]

【问题讨论】:

    标签: javascript node.js express mongoose


    【解决方案1】:

    我通过使用名为 populate 的 mongoose 功能解决了我自己的问题。 http://mongoosejs.com/docs/populate.html。我能够大大简化我的代码:

        router.route('/data')
        //get all data
        .get(function(req, res) {
            Attendee.find().populate('messages').exec(function(err, attendees){
                if (err) {res.send(err);}
                res.json(attendees);
            });
        }); 
    

    这段代码的真正魔力在于方案:

    var mongoose = require('mongoose');
    
    var AttendeeSchema = new mongoose.Schema({
        fullName: {
            type: String,
            require: true
        },
        dateJoined: {
            type: Date,
            require: true
        },
        phoneNumber: {
            type: String,
            required: true
        },
        messages: [{
            type: mongoose.Schema.Types.ObjectId, ref: "Message"
        }]
    });
    
    module.exports = mongoose.model('Attendee', AttendeeSchema);
    

    var mongoose = require('mongoose');
    
    var MessageSchema = new mongoose.Schema({
        _userID: {
            type: String,
            ref: 'Attendee'
        },
        phoneNumber: {
            type: String,
            require: true
        },
        date: {
            type: Date,
            require: true
        },
        body: {
            type: String,
            required: true
        },
        sid: {
            type: String,
            required: true
        }
    
    });
    
    module.exports = mongoose.model('Message', MessageSchema);
    

    【讨论】:

      【解决方案2】:

      主要问题是您在完全检索到结果之前在响应中发回了结果。您的 res.json(results)Message.find(...) 回调之外。此外,由于您在同一个回调中将参加者对象推送到结果数组上,它也会丢失,并且您返回的结果数组将只是原始的空数组。

      你需要更多这样的东西:

      router.route('/data')
      //get all data
      .get(function(req, res) {
          var results = [];
          Attendee.find(function(err, attendees) {
              if (err) {res.send(err);}
              else {
                  q.all(attendees.map(function(attendee) {
                      return Message
                          .find({userID: attendee._id}, "")
                          .exec()
                          .then(function(messages) {
                              results.push({
                                  attendee: attendee,
                                  messages: messages
                              });         
                           })
                  }))
                  .then(function() {
                      res.json(results);
                  })
              }
          });
      });
      

      【讨论】:

      • 是的,但这将在 forEach 循环的第一次迭代后返回结果。如果我有多个与会者怎么办? (我非常计划拥有)
      • 您当然是对的,已编辑答案。它使用了 Q,一个 promise 库:github.com/kriskowal/q
      猜你喜欢
      • 2015-08-23
      • 2012-06-08
      • 2021-09-18
      • 2019-07-15
      • 2023-04-09
      • 1970-01-01
      • 2021-08-20
      • 2019-02-19
      • 2015-10-23
      相关资源
      最近更新 更多