Let's say this is my MongoDB schema:
var shopSchema = new mongoose.Schema({
nameShop: String,
products: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Product'
}]
});
var productSchema = new mongoose.Schema({
nameProduct: String,
fruits: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Fruit'
}
]
});
var fruitSchema = new mongoose.Schema({
nameFruit: String,
price: Number
});
module.exports = {
Shop: mongoose.model('Shop', shopSchema),
Product: mongoose.model('Product', productSchema),
Fruit: mongoose.model('Fruit', fruitSchema)
}
I know that I can get data in this way, but result of that code is an "ugly" array
var Schema = require('../model/schema');
Schema.Shop.find({}).populate({
path: 'products',
model: 'Product',
populate: {
path: 'fruits',
model: 'Fruit'
}
}).exec(callback);
Is it possible to get data from this schema in way that I will have nice array? Eg:
var MyArray = [
{ nameShop: "Tesco", nameProduct: "New", nameFruit: "Apple", price: 10 },
{ nameShop: "Tesco", nameProduct: "New", nameFruit: "Pinapple", price: 4 },
{ nameShop: "Eko", nameProduct: "Old", nameFruit: "Kiwi", price: 8 },
{ nameShop: "Makro", nameProduct: "Fresh", nameFruit: "Pear", price: 7 },
{ nameShop: "Carefour", nameProduct: "New", nameFruit: "Orange", price: 6 }
];
You could go the aggregation framework route, which has the capacity to flatten the arrays through the $unwind
operator. This will generate a new record for each and every element of the list data field on which unwind is applied. It basically flattens the data.
After flattening the data you would require the $lookup
operator to do a "join" on the products
field to the products
collection. Repeat the process for the nested fruits schema.
Lets see an example (untested) to understand this better
var Schema = require('../model/schema');
Schema.Shop.aggregate([
{ "$unwind": "$products" },
{
"$lookup": {
"from": "products",
"localField": "products",
"foreignField": "_id",
"as": "product"
}
},
{ "$unwind": "$product" },
{ "$unwind": "$product.fruits" },
{
"$lookup": {
"from": "fruits",
"localField": "product.fruits",
"foreignField": "_id",
"as": "fruits"
}
},
{
"$project": {
"nameShop": 1,
"nameProduct": "$product.nameProduct",
"nameFruit": "$fruits.nameFruit",
"price": "$fruits.price",
}
}
]).exec(function (err, result){
if (err) throw err;
console.log(result);
})
DISCLAIMER : The above is untested code which only serves as a guide by making a couple of assumptions that you are running the code in a test environment with the latest MongoDB and mongoose versions that support the $lookup
operator AND that you can perform the same aggregation query in mongo shell.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.