I have a simple migration framework for mongo that is executing some scripts passed in it.
Now I want to migrate my LUUID to UUID. I wrote following:
function fixIds(collectionName) {
function uuidv4() {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
var collection = db.getCollection(collectionName);
var items = collection.find({}).toArray().map(x => Object.assign(x, { _id: UUID(uuidv4()) })); // replace legace UUID with standard UUID
collection.drop();
collection.insertMany(items);
}
fixIds("specialoffers");
Then I run it:
public static async Task<BsonValue> EvalAsync(this IMongoDatabase database, string javascript)
{
var client = database.Client as MongoClient;
if (client == null)
throw new InvalidOperationException("Client is not a MongoClient");
var function = new BsonJavaScript(javascript);
var op = new EvalOperation(database.DatabaseNamespace, function, null);
using (var writeBinding = new WritableServerBinding(client.Cluster, new CoreSessionHandle(new NoCoreSession())))
{
return await op.ExecuteAsync(writeBinding, CancellationToken.None).ConfigureAwait(false);
}
}
It executes, but it replaces LUUID values to other LUUID values. However, when I run very this script in my Robo 3T
shell it works as expected.
What is wrong with this code? Why it work from the shell only?
This guy worked for me:
function fixIds(collectionName) {
var collection = db.getCollection(collectionName);
var items = collection.find({}).toArray().map(x => Object.assign(x, { _id: new BinData(4, x._id.base64()) })); // replace legacy UUID with standard UUID
collection.drop();
collection.insertMany(items);
}
fixIds("specialoffers");
I replaced UUID(uuidv4())
with new BinData(4, x._id.base64()) })
and this is the only way to correcly update UUID version.