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

Async: Combining two mongodb collection using Async.forEach

我是 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 }
},...]

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

完成这个简单任务的最简单和最有效的方法是使用聚合框架,您可以在其中利用 mongo 的本机运算符,如 $match to filter the document stream to allow only matching documents to pass unmodified into the next pipeline stage and $lookup 对同一数据库中的付款集合执行左外连接,以过滤来自 "joined" 集合的文档以进行处理:

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