问题
I have searched online but could not find any match my case. Here is the situation.
I am using aggregate to combine one collection and one document which is from another collection together
restaurants.aggregate([
{
$match: {
_id: {
$in: idList
}
}
},
{
$lookup: {
from: "tags",
localField: "details.restaurantType",
foreignField: "details.restaurantType._id",
as: "types"
}
},
{
$project: {
restaurantName: "$details.restaurantName",
restaurantType: "$details.restaurantType",
type: {
$filter: {
input: "$types",
as: "type",
cond: {
$eq: ["$$type._id", "$details.restaurantType"]
}
}
},
currency: "$details.currency",
costPerPax: "$details.costPerPax"
}
}
]);
current result
The 'type' field in my current result is [], I need a matched value instead
[
{
"id": "5c20c7a0036dda80a8baabcc",
"restaurantName": "Villagio Restaurant Sutera Mall",
"type": [],
"currency": "RM",
"costPerPax": 22,
},
{
"id": "5c20ceb07715216d3c217b7a",
"restaurantName": "Thai Food Thai Now Sutera Mall",
"type": [],
"currency": "RM",
"costPerPax": 16,
}
]
expected result
I need the 'type' fields has match tag name from another collection like this
[
{
"id": "5c20c7a0036dda80a8baabcc",
"restaurantName": "Villagio Restaurant Sutera Mall",
"type": "Western",
"currency": "RM",
"costPerPax": 22,
},
{
"id": "5c20ceb07715216d3c217b7a",
"restaurantName": "Thai Food Thai Now Sutera Mall",
"type": "Thai",
"currency": "RM",
"costPerPax": 16,
}
]
Extra Information
two document from restaurants collection
{
"details": {
"restaurantName": "Villagio Restaurant Sutera Mall",
"restaurantType": "5c01fb57497a896d50f498a8"
},
"_id": "5c20c7a0036dda80a8baabcc",
"status": "OP",
"__v": 0
},
{
"details": {
"restaurantName": "Kingshahi Japanese Shop",
"restaurantType": "5c01fb57497a896d50f49879"
},
"_id": "5c20cb4fb7e75180480690c2",
"status": "OP",
"__v": 0
}
One document from tag collection
{
"_id": "5c01fb57497a896d50f49876",
"details": {
"restaurantTypeId": "5c01fb57497a896d50f49877",
"restaurantTypes": [
{
"_id": "5c01fb57497a896d50f49879",
"name": "Asian",
"counter": 1
},
{
"_id": "5c01fb57497a896d50f4987a",
"name": "Bakery",
"counter": 0
}
]
}
}
回答1:
You can use below optimised aggregation pipeline
db.restaurants.aggregate([
{ "$lookup": {
"from": "tags",
"let": { "restaurantType": "$details.restaurantType" },
"pipeline": [
{ "$match": {
"$expr": { "$in": ["$$restaurantType", "$details.restaurantTypes._id"] }
}},
{ "$unwind": "$details.restaurantTypes" },
{ "$match": {
"$expr": { "$eq": ["$details.restaurantTypes._id", "$$restaurantType"] }
}}
],
"as": "types"
}},
{ "$project": {
"restaurantName": "$details.restaurantName",
"restaurantType": "$details.restaurantType",
"type": { "$arrayElemAt": ["$types.details.restaurantTypes.name", 0] },
"currency": "$details.currency",
"costPerPax": "$details.costPerPax"
}}
])
来源:https://stackoverflow.com/questions/53966763/mongodb-lookup-on-one-documents-array-of-object