FindOneAndReplace (Upsert) not generating correct Object ID

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Works as Designed
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: CRUD
    • 🔵 Done
    • Dotnet Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      From the following community post, InsertOne gives a document back with an expected object ID but mimicing Upsert using FindOneAndReplace gives a zeroed out object ID.

      Sample code snippet attached below:

      using MongoDB.Driver;
      using MongoDB.Bson;
      using MongoDB.Bson.Serialization.Attributes;
      using System.Security.Cryptography.X509Certificates;
      using System.Xml.Xsl;public class DictionaryValue
      {
          public int Id;
          public string Value;
      }[AttributeUsage(AttributeTargets.Class, Inherited = false)]
      public class BsonCollectionAttribute : Attribute
      {
          public string CollectionName { get; }    public BsonCollectionAttribute(string collectionName)
          {
              CollectionName = collectionName;
          }
      }[BsonCollection("Documents")]
      public class MyDocumentType 
      {
          [BsonId]
          [BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]
          public ObjectId Id;
          public DateTime CreatedAt => Id.CreationTime;    public string TopLevelField;
          public Dictionary<string, DictionaryValue> Values;}
      class MongoService { 
          private MongoClient _client;
          private IMongoDatabase _db;
          private IMongoCollection<MyDocumentType> _collection;    public void Connect()
          {
              try
              {
                  var settings = MongoClientSettings.FromConnectionString("mongodb://localhost:27018");
                  _client = new MongoClient(settings);
                  _db = _client.GetDatabase("dictionaryTest");
                  Console.WriteLine("Connected to Mongo!");
                  _collection = _db.GetCollection<MyDocumentType>("Documents");
              }
              catch (Exception ex)
              {
                  Console.WriteLine("Error on connect to Mango database: {error}", ex);
                  throw;
              }
          }    public MyDocumentType UpsertOne(MyDocumentType doc)
          {
              var options = new FindOneAndReplaceOptions<MyDocumentType>
              {
                  IsUpsert = true,
                  ReturnDocument = ReturnDocument.After,
              };        var filter = Builders<MyDocumentType>.Filter.Eq(d => d.Id, doc.Id);
              var upsertedDoc = _collection.FindOneAndReplace(filter, doc, options);
              return doc;
          }    public MyDocumentType UpsertOneSlow(MyDocumentType doc)
          {
              var existing = _collection.Find(d => d.Id == doc.Id).FirstOrDefault();
              if (existing != null)
              {
                  _collection.ReplaceOne(d => d.Id == doc.Id, doc);
                  return doc;
              } else
              {
                  _collection.InsertOne(doc);
                  return doc;
              }
          }    public MyDocumentType InsertOne(MyDocumentType doc)
          {
              _collection.InsertOne(doc);
              return doc;
          }
      }class Program
      {
          static int Main(String[] args)
          {
              var document = new MyDocumentType();
              document.TopLevelField = "Dictionary of Integers";
              document.Values = new Dictionary<string, DictionaryValue>()
              {
                  { "1", new DictionaryValue {Id = 1, Value = "1"} },
                  { "2", new DictionaryValue {Id = 2, Value = "1"} },
                  { "3", new DictionaryValue {Id = 3, Value = "2"} },
              };        var db = new MongoService();
              db.Connect();        var documentWithZeroedId = db.UpsertOne(document);
              Console.WriteLine($"Upsert Document ID: {documentWithZeroedId.Id}");        var documentWithValidId = db.InsertOne(document);
              Console.WriteLine($"Insert Document ID: {documentWithValidId.Id}");        return 0;
          }
      } 

            Assignee:
            Oleksandr Poliakov
            Reporter:
            Rishit Bhatia
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: