我列出了一系列产品,每个产品都有自己的选项。例如:
蓝色连衣裙和红色连衣裙是产品, S , L , XS , S 和 M 是选项。选项模型引用了产品模型,我想检索所有产品,然后列出自己的选项。
我想用一个查询来实现它,我的问题是我从没有链接到其选项的产品开始。所以我开始寻找所有产品,并使用嵌套的然后与foreach循环我得到它的所有选项。然后我尝试将选项分配给产品对象(在我的情况下 productElem 在 forEach 中),但当我从范围中检索它时,它是空的。如何从产品查询开始填充选项?
产品架构:
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)
您的代码存在一些缺陷。 product ID
循环试图找到基于find()
的所有选项,这看起来像一个明显的方法,但这里的问题是find()
方法的异步性质。
由于forEach
的异步性质,find()
循环已完成,无需等待单个options
的结果,因此find()
尚未promises
人口稠密。在循环之后,它只是渲染&shop; list / listProduct',显然没有产品选项。
您可以做的是将所有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
$lookup
会根据$project
(即产品ID)package com.kafka.api.models;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
@JsonRootName("person")
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private String personalID;
private String country;
private String occupation;
public Person() {
}
@JsonCreator
public Person(@JsonProperty("name") String name,@JsonProperty("personalID") String personalID,
@JsonProperty("country") String country,@JsonProperty("occupation") String occupation){
this.name= name;
this.personalID = personalID;
this.country = country;
this.occupation = occupation;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPersonalID() {
return personalID;
}
public void setPersonalID(String personalID) {
this.personalID = personalID;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
@Override
public String toString() {
return "{" + " " + "Name :" + " " + name + " " + "ID :" + " "
+ personalID + " " + "Country :" + " " + country + " "
+ "Occupation :" + " " + occupation + "}";
}
}
对选项进行分组,以填充产品对象,string headLine = "Example";
Console.WriteLine(headLine);
for (char i = '='; i <= headLine.Length; i += '=')
{
Console.WriteLine(i);
}
会将结果返回给您你要的那个。
了解mongodb Aggregation,$group,$lookup,$project以便更好地了解它。