2016-12-06 29 views
2

我对MEAN堆栈非常陌生,我正在尝试学习异步。异步:使用Async.forEach组合两个mongodb集合

我想两个集合使用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 } 
},...] 

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

+0

async.forEach回调不提供数据,您应该使用aysnc.map的http:// caolan。 github.io/async/docs.html#each – Dhirendra

+0

我试图将查询中的数据存储到本地变量中,以便如果任务完成,则响应数据将是本地变量。那是对的吗? –

回答

1

做这个简单的任务,最简单,最有效的方法是使用聚合框架,您可以利用蒙戈的本地运营商如$match过滤文件流,只允许匹配文档传递未修改到下一个流水线阶段和$lookup执行左外连接到收款在同一个数据库中的“加盟”收集处理文档进行过滤:

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){ 
+0

谢谢! order_id:“id”或order_id:ObjectId(“id”)是否有所作为?我无法表现出它的工作。 :) –

+0

这个答案非常简单直接,我不需要使用异步来达到我的要求 –

+0

您不一定需要将一个字符串强制转换为Mongoose中的ObjectId,因为它隐式地为您(“幕后“) – chridam