2017-10-07 115 views
1

我有一个产品列表,每个产品都有自己的选项。例如:填充另一个对象引用的对象

  • 蓝色礼服(S - L)
  • 红服饰(XS - S - M)

蓝色礼服红服饰是产品,小号L,XS,SM是选项。选项模型有对产品模型的参考,我想检索所有产品,然后列出他们自己的选项。

我想用一个查询来实现它,我的问题是我从没有链接到它的选项的产品开始。所以我开始找到所有的产品,并与一个嵌套的然后与foreach循环我得到它的所有选项。然后我尝试将该选项分配给产品对象(在我的情况下,产品Ellem内部的for each),但是当我检索出它的范围当然是空的。如何填充从产品查询开始的选项?

产品架构:

var schema = new Schema({ 
    imagePath: {type: String}, 
    title: {type: String, required: true}, 
    description: {type: String, required: true} 
}); 

选项模式:

var productOptionSchema = new Schema({ 
    type: {type: String, enum: ['grams'], default: 'grams', required: true}, 
    value: {type: String, required: true}, 
    price: {type: Number, required:true}, 
    product: {type: Schema.Types.ObjectId, ref: 'User', required:true} 
}); 

在这里,我试图寻找产品

router.get('/shop/products/list', isLoggedIn, function (req, res, next) { 
    Product.find() 
    .then(function (products) { 
     products.forEach(function(productElem) { 
     ProductOption.find({product: productElem._id}) 
      .then(function (options) { 
      productElem['options'] = []; 
      options.forEach(function(optionElem) { 
       productElem['options'].push(optionElem); 
      }); 
      }); 
     }); 
     res.render('shop/listProduct', {user:req.user, csrfToken: req.csrfToken(), messages:messages, partialCustom: 
     }); 
    }) 
    .catch(function (err) { 
     console.log('Error ' + err.code + ': ', err.message); 
     res.status(500).send('Failed to get the Product List from the DB: ' + err); 
    }); 
}); 
+0

你的问题不是很清楚。请编辑该问题以使其更易于理解。 –

回答

0

有在你的代码中的一些漏洞后获得的选项。 forEach循环试图找到所有基于product ID的选项,这看起来像是一个明显的方法,但这里的问题是find()方法的异步性质。

由于find()的异步性质,forEach环被完成,而无需等待从个人find()的结果,作为其结果是options是尚未填充。在循环之后,它只是呈现'shops/listProduct',这显然没有产品选项。

您可以做的是将所有find()推入promises数组中,等待所有使用Promise.all()的承诺返回。在所有承诺成功完成后做res.render('shops/listProduct',{...})

备用方法:

我有一个更简单的方法来达到你想要使用aggregation什么。

试试这个:

ProductOption.aggregate([{ 
    $group : { 
     _id : product, 
     options : {$push : "$$ROOT"} 
    } 
},{ 
    $lookup : { 
     from : "products", 
     localField : "_id", 
     foreignField : "_id", 
     as : "product" 
    } 
},{ 
    $unwind : { 
     path : "$product", 
     preserveNullAndEmptyArrays : true 
    } 
},{ 
    $project : { 
     _id : "$product._id" 
     imagePath : "$product.imagePath", 
     title : "$product.title", 
     description : "$product.description", 
     options : "$options" 
    } 
}],function(err,result){ 
    //result will have all the products with their options 
}); 

$group意志集团基础上,product(我的选项。e产品ID)$lookup将填充产品对象,并且$project将以您想要的方式返回结果。

阅读关于mongodb Aggregation$group$lookup$project了解它更好。