异步:使用Async.forEach组合两个mongodb集合

时间:2016-12-06 08:43:00

标签: node.js mongodb mongoose mongodb-query async.js

我是MEAN堆栈的新手,我正在尝试学习异步。

我尝试使用async

组合来自mongodb的两个集合

并应用此iterate over a collection, perform an async task for each item,我试图学习执行此简单任务的最简单有效的方法,因此很容易理解。

var OrderSchema = new mongoose.Schema({

    menu_id: {type:mongoose.Schema.Types.ObjectId, ref: 'Foods'},
    menu_name: {type:String,required:false},
    customer_id: {type:String,required: true,},
    customer_name:{type:String, required: false},
    table_no:{type:String,required:true},
    cooking:{type:Boolean, require:false, default:false},
    ready:{type:Boolean,default:false},
    served:{type:Boolean,default:false},
    paid:{type:Boolean, default:false},
    price: {type:Number, default:0},
    quantity: {type:Number,default:0},
    created_at: { type: Date, default: Date.now }

}

付款模式

var mongoose = require('mongoose');

var PaymentSchema = new mongoose.Schema({
   order_number: {type:String, required: true, index: true},
   order_id: {type:mongoose.Schema.Types.ObjectId, ref: 'Orders'},
   date: { type: Date, default: Date.now },
   customer_id: {type:mongoose.Schema.Types.ObjectId, ref: 'User'},
   amount : { type: Number, required:true },
   company_id: {type:mongoose.Schema.Types.ObjectId, ref: 'Company'}
},
{
  toJSON: { virtuals: true },
  toObject: { virtuals: true }
});

module.exports = mongoose.model('Payments', PaymentSchema);

这是我的代码

var data = req.body;
var calls = [];
var local_orders = [];
var OrderModel = require('../models/Order');
var PaymentModel = require('../models/Payment');

OrderModel.find({'table_no': data.table_no}, function(err,orders){

    async.forEach(orders, function(vorders, callback){

        PaymentModel.find({order_id:vorders.id}, function(err, payments){
                vorders.payments = 'payments';
                    local_orders.push(vorders)
                });

                return callback(null, local_orders);

            }, function(err,local_orders){
                if(err){
                    res.status('500').send(err);
                }
                res.send(local_orders)
        });

})

我希望收到这样的JSON对象,但我得到的是未定义的。

[{ menu_id: {type:mongoose.Schema.Types.ObjectId, ref: 'Foods'},
   menu_name: {type:String,required:false},
   user_id: {type:String,required: true,},
   customer_name:{type:String, required: false},
   table_no:{type:String,required:true},
   cooking:{type:Boolean, require:false, default:false},
   ready:{type:Boolean,default:false},
   served:{type:Boolean,default:false},
   paid:{type:Boolean, default:false},
   price: {type:Number, default:0},
   quantity: {type:Number,default:0},
   created_at: { type: Date, default: Date.now },
   payments : [{ payment1 },{ payment2 }
},...]

如果您需要更多说明或缺少某些内容,请发表评论。谢谢!干杯!

1 个答案:

答案 0 :(得分:1)

执行此简单任务的最简单,最有效的方法是使用聚合框架,您可以利用mongo的本地运营商(如 $match )将文档流过滤到仅允许匹配的文档未经修改地传递到下一个管道阶段,并且 $lookup 执行左外部联接到同一数据库中的付款集合,以过滤来自"加入&的文档#34;处理集合:

var data = req.body;
OrderModel.aggregate([
    { "$match": { "table_no": data.table_no } },
    {
        "$lookup": {
            "from": "payments",
            "localField": "_id",
            "foreignField": "order_id",
            "as": "payments"
        }
    }
]).exec(function (err, result){
    if (err){
        res.status('500').send(err);
    }
    res.send(result)
});

但是,现在你的代码失败了

PaymentModel.find({ order_id: vorders.id }, function(err, payments){

由于vorders对象没有任何id密钥,但是_id,所以应该是

PaymentModel.find({ "order_id": vorders._id }, function(err, payments){