Description
After reworking my data construct, I want to embed a document (or parts of it) from a different collection. Pay your attention to event.tags[]. Currently, there are only their stringified _ids (as plain string, no ObjectId!) stored, but I want to migrate their content, like {tags.name, tags._id}. I want to update/replace the original event.tags with the content of tag-documents.
Data
Collection "events"
db.events.insertMany([{
"_id" : ObjectId("5f6c5b0594911c0b7231643d"),
"title" : "Test Event",
"tags" : [
"5fd8cef2368c625a9d7516cb"
]
},
{
"_id" : ObjectId("5fb3896afc13ae2ed1000000"),
"title" : "Test Event 2",
"tags" : [
"5fd8cef2368c625a9d7516cb",
"5fd8cfb04a4a6063ab4ca4bf",
"5fd8cfb04a4a6063ab4ca4c0"
]
}
]);
Collection "tags"
db.tags.insertMany([{
"_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
"name" : "Foo",
"createdAt" : ISODate("2020-12-15T14:57:54.096Z")
},
{
"_id" : ObjectId("5fd8cfb04a4a6063ab4ca4bf"),
"name" : "Bar",
"createdBy" : "[email protected]",
"createdAt" : ISODate("2020-12-16T14:57:54.096Z")
},
{
"_id" : ObjectId("5fd8cfb04a4a6063ab4ca4c0"),
"name" : "Foobar",
"createdAt" : ISODate("2020-12-17T14:57:54.096Z")
}
]);
Expected result
I want to achieve to embed some/all fields of collection "tags" matched by "events.tags" <-> "tags._id" as an array of embedded/nested documents. This will be part of a migration script, running over mongoDB API >4.0 thru node.js.
Goal: I want to replace an Array of Strings (see collection events) with certain information of a DIFFERENT collection (see collection tags) and save it back to collection events (migrate process). So I assume, I have to fetch/lookup something from tag collection and need a mechanism to replace the string (events.tags[x]) with complex objects ({tags._id, tags.name})
{
"_id" : ObjectId("5f6c5b0594911c0b7231643d"),
"title" : "Test Event",
"tags" : [{
"_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
"name" : "Foo",
"createdAt" : ISODate("2020-12-15T14:57:54.096Z")
}]
},
{
"_id" : ObjectId("5fb3896afc13ae2ed1000000"),
"title" : "Test Event 2",
"tags" : [{
"_id" : ObjectId("5fd8cef2368c625a9d7516cb"),
"name" : "Foo"
},
{
"_id" : ObjectId("5fd8cfb04a4a6063ab4ca4bf"),
"name" : "Bar"
},
{
"_id" : ObjectId("5fd8cfb04a4a6063ab4ca4c0"),
"name" : "Foobar"
}]
}
Baby steps
I tried to use the aggregation pipeline and started by matching and lookup their content to replaceWith in the last step. I am not too familiar to solve this via the aggregation pipeline.
db.getCollection('events').aggregate([
{ $match: { tags: { "$exists" : true } } },
{
$lookup:
{
from: "tags",
localField: "tags",
foreignField: "_id",
as: "taags"
}
},
])