2017-10-07 69 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瞭解它更好。