C# driver 2.11.1 allegedly use Different Guid representation for insert and for find

Hi people,
In a test That I had done it looks to me that Different Guid representation is used for insert and for find operations.
The following example that I constructed for illustration use the c# driver 2.11.1 and tested on MongoDB 4.2.5 and 4.2.9 servers.

class House
{
public int Id { get; set; }
public Guid ClientId { get; set; }
}

class Program
{
private static IMongoDatabase _database;
private static IMongoCollection Houses;

    static void Main(string[] args)
    {
        Init();
        InsertFindHouse().GetAwaiter().GetResult();
    }

    private static async Task InsertFindHouse()
    {
        Guid clientId = new Guid("1A76AD2A-4FF6-4291-860E-51C5C34AA890");

        // Insert
        House house = new House
        {
            Id = 1,
            ClientId = new Guid("1A76AD2A-4FF6-4291-860E-51C5C34AA890")
        };
        await Houses.InsertOneAsync(house);

        // Find
        FilterDefinition<House> filter = Builders<House>.Filter.Eq(x => x.ClientId, clientId);
        var result = await Houses.Find(filter).ToListAsync();
    }

    private static void Init()
    {
        BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));

        string connectionString = ConfigurationManager.AppSettings["testConnectionString"];
        MongoUrl mongoUrl = MongoUrl.Create(connectionString);
        MongoClientSettings settings = MongoClientSettings.FromUrl(mongoUrl);
        string dbName = mongoUrl.DatabaseName;
        MongoClient mongoClient = new MongoClient(settings);
        _database = mongoClient.GetDatabase(dbName);
        Houses = _database.GetCollection<House>("houses");
    }
}

The Find function generates the following (taken from the MongoDB log file)
2020-08-29T14:24:21.763+0300 D2 COMMAND [conn4] run command test.$cmd { find: “houses”, filter: { ClientId: BinData(3, 2AAD761AF64F9142860E51C5C34AA890) }, $db: “test”, lsid: { id: UUID(“4b4f1b41-0ada-4cb6-bcdc-837923e7629b”) } }

This query does not return any document, probably, because the format of the Guid is BinData(3, 2AAD761AF64F9142860E51C5C34AA890).

When I query it from the mongo shell, it returns the following correct answer:

db.houses.find({ “ClientId” : UUID(“1a76ad2a-4ff6-4291-860e-51c5c34aa890”) })
{ “_id” : 1, “ClientId” : UUID(“1a76ad2a-4ff6-4291-860e-51c5c34aa890”) }

It looks like that in the sample application the driver saved the Guid in one format and query it in another format.
Am I doing something wrong?

Thanks,
Itzhak

Hi,

I have the same issue - after upgrade from 2.8.x to 2.11.2 and changing from
BsonDefaults.GuidRepresentation = GuidRepresentation.Standard
to
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard))

I get the issue that find (e.g. in a filter ReplaceOneAsync) does not work anymore. I guess it is the same issue as above, the find uses BinData(3,…) instead of BinData(4, …) . Is the only fix to roll back to a previous version of the driver??

Here a small repro, however in F#:

#I "../../../../.nuget/packages/"
#r @"mongodb.driver/2.11.2/lib/netstandard2.0/MongoDB.Driver.dll"
#r @"mongodb.driver.core/2.11.2/lib/netstandard2.0/MongoDB.Driver.Core.dll"
#r @"mongodb.bson/2.11.2/lib/netstandard2.0/MongoDB.Bson.dll"
#r @"mongodb.libmongocrypt/1.0.0/lib/netstandard1.5/MongoDB.Libmongocrypt.dll"
#r @"dnsclient/1.3.2/lib/netstandard2.0/DnsClient.dll"

open System
open MongoDB.Driver
open MongoDB.Driver.Core
open MongoDB.Bson
open MongoDB.Bson.Serialization.Attributes
open MongoDB.Bson.Serialization
open MongoDB.Bson.Serialization.Serializers

//BsonDefaults.GuidRepresentation <- GuidRepresentation.Standard    // this is deprecated but works!
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard)) // this does not work!

let mongo = MongoClient("mongodb://localhost:27017")

let db = mongo.GetDatabase "TestDB"

type TestEntity = {
    [<BsonId>]
    Id: Guid

    Message: string

    [<BsonElement("lastModOn")>]
    LastModifiedOn: DateTime
}

let col = db.GetCollection<TestEntity>("testEntities11")

let te1 = { Id = Guid.NewGuid(); Message="Bla"; LastModifiedOn = DateTime.UtcNow }

let result = col.InsertOneAsync (te1) |> Async.AwaitTask |> Async.RunSynchronously

//let filter = sprintf """{ _id:UUID('%s')}""" (te1.Id.ToString())    // this works only with BsonDefaults.GuidRepresentation <- GuidRepresentation.Standard
let filter = sprintf """{ _id:BinData(4, '%s')}""" (BsonBinaryData(te1.Id, GuidRepresentation.Standard).AsByteArray |> System.Convert.ToBase64String )    // this works only with BsonDefaults.GuidRepresentation <- GuidRepresentation.Standard
let filterDef: BsonDocumentFilterDefinition<TestEntity> = BsonDocumentFilterDefinition(BsonDocument.Parse(filter))

//let filterDef = ExpressionFilterDefinition<TestEntity>(fun x -> x.Id.Equals(Guid.Parse("7da6b8d1-bd8e-4df6-9129-1f9e873b779a")))    // this does not work
//let filterDef = Builders<TestEntity>.Filter.Eq(StringFieldDefinition<Guid>("Id"), Guid.Parse("7da6b8d1-bd8e-4df6-9129-1f9e873b779a"))    // this does not compile

let options = ReplaceOptions()
options.IsUpsert <- false

let te2 = { te1 with Message="Bla2"; LastModifiedOn = DateTime.UtcNow }

let result2 = col.ReplaceOneAsync (filterDef, te2, options) |> Async.AwaitTask |> Async.RunSynchronously
result2.ModifiedCount = 0L

Hi Deyan,

You can add to your code at the very beginning of your program the following:
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;

The point is that this property is marked as Obsolete.
So far, I’d not seen any other comments about this issue.

Regards,
Itzhak

Thanks a lot, Itzhak, I found in the meantime this:

https://jira.mongodb.org/projects/CSHARP/issues/CSHARP-3179?filter=allopenissues

and

https://jira.mongodb.org/browse/CSHARP-3195

with the same recommendation … but now I have compilation warning for the next months/years to come … Strange why the driver has been changed in such a breaking (at least for our codebase) way - all of a sudden many integration tests starting failing, only change just being the package reference version …