Reputation: 4078
Well, someone done goofed. Wasn't me, but I get to fix it. What I need to do, is replace the _id
of each and every document in the collection with a new UUID.
My plan was aggregating the entire collection, use $addFields
to replace the _id
, then merge it back into itself, replacing the records. Fortunately, there is a secondary (composite) key I can use for merging, so I'm good there — I think, because I haven't gotten there yet.
The problem I face is generating a unique (that's kinda the point of it) UUID during the $addFields
stage.
db.foo.agregate([
{
$addFields: {
// I really just need the UUID string itself, hence the split
'_id': UUID().toString().split('"')[1]
}
}
// here's where the merge would go
])
The problem here is that UUID()
is called only once, so I get all the same IDs. That's not quite what I want.
Now the tedious way would be to do this one by one, from a loop. But is there a way to do this from within an aggregation pipeline in one go?
Now I found this question asking basically the same question, but it was solved by not using an UUID, using sequential keys instead, so it really isn't an answer to my question.
Upvotes: 3
Views: 3857
Reputation: 4452
So this answer is just to generate unique UUID
s by calling UUID()
from a $function. Try this:
db.collectionName.aggregate([
{
$addFields: {
_id: {
$function: {
body: function() {
return UUID().toString().split('"')[1];
},
args: [],
lang: "js"
}
}
}
}
])
btw, its only works in MongoDB version >= 4.4. Output:
/* 1 */
{
"_id" : "5dc9316a-50a8-4013-8090-06fc66cdce9f",
"dummy" : "data"
},
/* 2 */
{
"_id" : "062ebc8f-4455-4a81-a9e0-34f6c7132cab",
"dummy" : "data"
},
/* 3 */
{
"_id" : "94eef4b8-9c0e-4910-a1cb-58443a63a036",
"dummy" : "data"
}
Upvotes: 4
Reputation: 14490
If what you need to do is
What I need to do, is replace the _id of each and every document in the collection with a new UUID.
... and you can use ObjectIds instead of UUIDs, then:
The server should generate new _ids for each document during the insert.
Then:
Upvotes: 1