Find an object by GUID using MongoDB Driver with a registered class map

253 Views Asked by At

How do I find a mongo document by GUID? The c# POCO has an Id property that is stored in the mongo database.

The class map for the POCO is registered and called before a client is configured:

BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
    cm.AutoMap();
    cm.MapIdProperty(m => m.MyId)
        .SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
});

Now a document is stored in the database correctly by the looks of it: MongoDB Compass Screenshot

However, retrieving the document using a builder yields no result:

Guid myGuidId = ...;
var filterBuilder = Builders<MyClass>.Filter;
var filter = filterBuilder.Eq(d => d.MyId, myGuidId);
return Collection.Find(filter).FirstOrDefaultAsync();

The odd thing is that this query retrieves documents when doing either of these from the start:

  • Serialise as string cm.MapIdProperty(m => m.SimulationId).SetSerializer(new GuidSerializer(BsonType.String))
  • Using the obsolete global declaration for GUID serialisation BsonDefaults.GuidRepresentation = GuidRepresentation.Standard
1

There are 1 best solutions below

0
dododo On

This behavior is related to guid representation mode configured by default (V2). You can read about this here or in the question here

To work with your code, apply configuration as below:

        BsonClassMap.RegisterClassMap<MyClass>(cm =>
        {
            cm.AutoMap();
            cm.MapIdProperty(m => m.Value)
                .SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
        });

        var value = Guid.NewGuid();
        var filterBuilder = Builders<MyClass>.Filter;
        var filter = filterBuilder.Eq(d => d.Value, value);
        var db = new MongoClient().GetDatabase("db");

        // Option 1 with MongoCollectionSettings 
        var coll = db.GetCollection<MyClass>("coll1", new MongoCollectionSettings { GuidRepresentation = GuidRepresentation.Standard });
        coll.InsertOne(new MyClass() { Value = value });

        var result = coll.Find(filter).ToList(); // one record returned
        Console.WriteLine(result.Count);

        // Option 2 (Preferable) with BsonDefaults.GuidRepresentationMode.V3
        BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;

        coll = db.GetCollection<MyClass>("coll2");
        coll.InsertOne(new MyClass() { Value = value });
        result = coll.Find(filter).ToList();  // one record returned
        Console.WriteLine(result.Count);