Reputation: 23
I'm joining two collections, but the result of trends is an array, each item always has only one trend, how do I remove the trend inside array?
'Items' collection:
{
"itemid" : "370",
"name" : "A"
},
{
"itemid" : "378",
"name" : "B"
}
'Trends' collection
{
"itemid" : "370",
"max" : "715705",
},
{
"itemid" : "378",
"max" : "35346",
}
Command executed:
db.items.aggregate([
{
$lookup: {
from: "trends",
localField: "itemid",
foreignField: "itemid",
as: "trend"
}
}
])
Result:
{
"itemid" : "370",
"name" : "A",
"trend" : [ // unexpected array, the result is always a single 'trend'
{
"itemid" : "370",
"max" : "715705",
}
]
},
...
Expected:
{
"itemid" : "370",
"name" : "A",
"trend" : { // yeah, without array
"itemid" : "370",
"max" : "715705",
}
},
...
Upvotes: 2
Views: 778
Reputation: 17935
It's not an unexpected result, as $lookup
would result in retrieving all matched documents into an array i.e; trend
will be an array in your case. It's for a reason, Assume if you're joining collection A
with collection B
& documents in collection A
might multiple matching documents in collection B
then all those documents from collection B
are pulled into an array of that relative document of collection A
in your case trend
field. Here if you wanted to get object inside it you need to do one of these ::
db.items.aggregate([
{
$lookup: {
from: "trends",
localField: "itemid",
foreignField: "itemid",
as: "trend"
}
},
{ $addFields: { trend: {$arrayElemAt : ["$trend", 0] } } } // This stage is going re-write trend field with first object from trend array created by $lookup stage.
])
(Or)
db.items.aggregate([
{
$lookup: {
from: "trends",
localField: "itemid",
foreignField: "itemid",
as: "trend"
}
},
{ $unwind: { path: "$trend", preserveNullAndEmptyArrays: true } }
])
Note : When you use $unwind you need to be cautious that you need to use preserveNullAndEmptyArrays
option as if trend
is an []
- which means no match found in collection B
, then $unwind
is going to remove all collection A
documents with trend :[]
in the final aggregation result.
Upvotes: 2
Reputation: 151
You can do it with $unwind pipeline stage
db.items.aggregate([
{
$lookup: {
from: "trends",
localField: "itemid",
foreignField: "itemid",
as: "trend"
}
},
$unwind:"$trend"
])
Upvotes: 3