Reputation: 195
I have a document with a tree structure:
{
"_id": "62e1f19f094a5696fd18f4e9",
"parent": null,
"children": [
{
"_id": "44e1f19f094a5696fd18f4o7",
"parent": "62e1f19f094a5696fd18f4e9",
"children": [
{
"_id": "62e1f19f094a5696fd18f4e9",
"parent": "44e1f19f094a5696fd18f4o7",
"children": []
}
]
}
]
}
I want to add a new field "id"
(without the underscore) which refers to "_id"
to each document even if it is a child or parent
I tried to do something like this:
$addFields: {id: $_id, children.id: $children._id}
but in doesn't work
so, the final result I want to get
{
"_id": "62e1f19f094a5696fd18f4e9",
"id": "62e1f19f094a5696fd18f4e9",
"parent": null,
"children": [
{
"_id": "44e1f19f094a5696fd18f4o7",
"id": "44e1f19f094a5696fd18f4o7",
"parent": "62e1f19f094a5696fd18f4e9",
"children": [
{
"_id": "62e1f19f094a5696fd18f4e9",
"id": "62e1f19f094a5696fd18f4e9",
"parent": "44e1f19f094a5696fd18f4o7",
"children": []
}
]
}
]
}
Upvotes: 1
Views: 152
Reputation: 16033
Based on a question by @rickhg12hs:
It can be done, but I agree with @turivishal that if you are doing it, it is reasonable to store it once (a minor change to the query):
db.collection.aggregate([
{
$replaceRoot: {
newRoot: {
$function: {
body: "function drill(r) {r.id = r._id; if (r.children.length > 0) { for (let elem of r.children) { drill(elem)}} return r};",
args: [
"$$ROOT"
],
lang: "js"
}
}
}
}
])
See how it works on the playground example
For storing on the db, instead of aggregate
use an update
with pipeline, like this
Upvotes: 2