I have 3 mongodb collection with many to many relation, productfeatures collection is the relation collection.
db={
"products": [
{
"id": 1,
"name": "product 1"
}
],
"features": [
{
"id": 101,
"name": "width"
},
{
"id": 102,
"name": "length"
},
{
"id": 103,
"name": "height"
}
],
"productfeatures": [
{
"productId": 1,
"featureId": 101,
"value": "3"
},
{
"productId": 1,
"featureId": 102,
"value": "4"
},
{
"productId": 1,
"featureId": 103,
"value": "5"
}
]
}
I want to get a product's all features like the following, how can this be done?
[
{
"id": 1,
"name": "product 1",
"productfeatures": [
{
"feature": "width",
"value": "3"
},
{
"feature": "length",
"value": "4"
},
{
"feature": "height",
"value": "5"
}
]
}
]
I know how to get the productfeatures with lookup stage:
db.products.aggregate([
{
$match: {
id: 1
}
},
{
$lookup: {
from: "productfeatures",
localField: "id",
foreignField: "productId",
as: "productfeatures"
}
}
])
But I also want to join to the features collection to get the feature name.
You can use mongodb aggregation pipeline
with multiple $lookup
stage to achieve this.
You were going on the right path, You needed to add one $unwind
stage(to unwind the result of first lookup
stage) and $lookup
stage, and finally to group all the results, you would need a final $group
stage, to combine all features in one array.
Try this :
db.products.aggregate([
{
$match: {
id: 1
}
},
{
$lookup: {
from: "productfeatures",
localField: "id",
foreignField: "productId",
as: "productfeatures"
}
},{
$unwind : "$productfeatures"
},{
$lookup : {
from : "features",
local : "productfeatures.featureId",
foreignField : "id",
as : "feature"
}
},{
$unwind : "$feature"
},{
$group : {
_id : "$_id",
name : {$first : "$name"},
productfeatures : {$push : "$feature"}
}
}
])
Please read about $group , $unwind , $lookup for more details.
You can use below aggregation
db.products.aggregate([
{ "$match": { "id": 1 }},
{ "$lookup": {
"from": "productfeatures",
"let": { "productId": "$id" },
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$$productId", "$productId"] }}},
{ "$lookup": {
"from": "features",
"let": { "featureId": "$featureId" },
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$id", "$$featureId"] }}}
],
"as": "productfeatures"
}},
{ "$project": {
"value": 1,
"feature": { "$arrayElemAt": ["$productfeatures.name", 0] }
}}
],
"as": "productfeatures"
}}
])
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.