Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-40185

stitch lib handles initialization for upserted doc differently than server when update is a replacement

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.1.11
    • Affects Version/s: None
    • Component/s: Querying
    • None
    • Fully Compatible
    • ALL
    • Query 2019-04-22

      With an empty data set, running an update operation against the server to perform a document replacement uses the _id in the query to initialize it:

      local:PRIMARY> db.test.update({$and:[{_id: 1000}]}, {foo:10000}, {upsert:true})

      WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 1000 })

      local:PRIMARY> db.test.find()

      {{

      { "_id" : 1000, "foo" : 10000 }

      }}

       

      However doing the equivalent operation through the stitch library doesn't seem to take into account the query when initializing the upserted doc in the same manner. Here is a failing test case:

       
      	t.Run("upsert with a compound expression query should initialize upserted doc correctly with replacement", func(t *testing.T) {
      		matcher, err := stitchmongo.NewMatcher(bson.D{{"$and", []interface{}{
      			bson.D{{"_id", 1000}},
      		}}})
      		u.So(t, err, gc.ShouldBeNil)
      		defer matcher.Close()
      		updater, err := stitchmongo.NewUpdater(
      			bson.D{{"z", 3}},
      			matcher,
      		)
      		u.So(t, err, gc.ShouldBeNil)
      		defer updater.Close()
      		result, err := updater.ApplyUpsert()
      		u.So(t, err, gc.ShouldBeNil)
      		u.So(t, result.UpdatedDocument, gc.ShouldResemble, bson.D{{"_id", 1000}, {"z", 3}})
      		u.So(t, result.IsReplacement, gc.ShouldBeTrue)
      	})
      
       

      Interestignly though the same operation does work equivalently to the server when the update uses $ modifiers instead. For example, the following test passes:

      	t.Run("upsert with a compound expression query should initialize upserted doc correctly with update modifiers", func(t *testing.T) {
      		matcher, err := stitchmongo.NewMatcher(bson.D{{"$and", []interface{}{
      			bson.D{{"_id", 1000}},
      			bson.D{{"x", 50}},
      		}}})
      		u.So(t, err, gc.ShouldBeNil)
      		defer matcher.Close()
      		updater, err := stitchmongo.NewUpdater(
      			bson.D{{"$set", bson.D{{"z", 3}}}},
      			matcher,
      		)
      		u.So(t, err, gc.ShouldBeNil)
      		defer updater.Close()
      		result, err := updater.ApplyUpsert()
      		u.So(t, err, gc.ShouldBeNil)
      		u.So(t, result.UpdatedDocument, gc.ShouldResemble, bson.D{{"_id", 1000}, {"x", 50}, {"z", 3}})
      		u.So(t, result.IsReplacement, gc.ShouldBeFalse)
      	})
      
      

            Assignee:
            justin.seyster@mongodb.com Justin Seyster
            Reporter:
            mikeo@mongodb.com Michael O'Brien
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: