Hi all,
We need to switch to subtype 4 for UUID. There is a large collection and most UUIDs has subtype 3.
We followed this recommendation from this post
- For small data, create a new collection, migrate data, ensure GUIDs use subtype 4;
- For large collections, use a custom IBsonSerializer that reads subtype 3 and 4, but always writes as subtype 4.
So, we created a custom serializer and it works as expected.
`
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
BsonSerializer.RegisterSerializer(new GuidAdaptiveSerializer());
BsonSerializer.RegisterSerializer(new NullableGuidAdaptiveSerializer());
`
But how can we filter the data by ignoring subtypes?
for old items this doesn’t work:
var filter = Builders<UserModel>.Filter.Eq("_id", "158d268a-5956-4455-bb68-74ae2ed49b2e");
var item = collection.Find(filter).FirstOrDefault();
Hi, @Roman_Marusyk,
Welcome to the MongoDB Community Forums. Querying GUIDs with different representations is a bit challenging because the server does a binary comparison of the data, which includes both the binary subtype and actual byte ordering. Thus you can’t ignore the subtype in the comparison because the actual bytes are written in a different order on disk.
If you don’t know whether a particular document is written with a subtype 3 or subtype 4 GUID, you can write a query to match both cases:
#pragma warning disable CS0618 // Type or member is obsolete
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3; // you must be in V3 mode for this to work
#pragma warning restore CS0618 // Type or member is obsolete
var client = new MongoClient();
var db = client.GetDatabase("test");
var coll = db.GetCollection<UserModel>("guids");
var guid = Guid.NewGuid();
var id3 = new BsonBinaryData(guid, GuidRepresentation.CSharpLegacy);
var id4 = new BsonBinaryData(guid, GuidRepresentation.Standard);
var builder = Builders<UserModel>.Filter;
var filter = builder.Or(
builder.Eq("Id", id3),
builder.Eq("Id", id4));
var query = coll.Find(filter);
Console.WriteLine(query);
This results in the following query being sent to the server:
find({ "$or" : [{ "_id" : HexData(3, "5cf29873-9067-284c-aab1-c57cfa204327") }, { "_id" : UUID("7398f25c-6790-4c28-aab1-c57cfa204327") }] })
Hope that helps.
Sincerely,
James