Skip to content

updateOne(..., { upsert: true}) Cannot locate upserted record. #152

Open
@sinclairzx81

Description

Hi, thanks for this library, it is very useful. I may have stumbled across a small issue with upsert and subsequent matching on Mongo identifiers. A repro of the issue is below.

// Using updateOne(..., { upsert: true }) with an existing identifier. The expectation here is that 
// upserted record would use the identifier passed in the filter.  However that doesn't
// appear to be the case.
async function repro() {
    const mongo_mock   = require('mongo-mock')
    const client       = new mongo_mock.MongoClient()
    const db           = await client.connect('mongodb://localhost:27017/db')
    const vectors      = db.collection('vectors')
    
    const _id          = new mongo_mock.ObjectID()
    const updateResult = await vectors.updateOne({ _id }, { x: 1, y: 2, z: 3 }, { upsert: true })
    const findResult   = await vectors.findOne({ _id })

    console.log(updateResult) // result: { result: { ok: 1, nModified: 1, n: 1 }, ... }
    console.log(findResult)   // result: null
                              // expect: { _id: ObjectId(...), x: 1, y, 2, z: 3 }
}

repro()

I can confirm the record is being written with this subsequent repro, however unsure about the encoding used to express the identifier, or why this is failing to match. (Edit: it appears mongo-mock may just be ignoring the _id for the filter and generating a new _id in these cases)

async function repro2() {
    const mongo_mock   = require('mongo-mock')
    const client       = new mongo_mock.MongoClient()
    const db           = await client.connect('mongodb://localhost:27017/db')
    const vectors      = db.collection('vectors')
    
    const _id          = new mongo_mock.ObjectID()
    const updateResult = await vectors.updateOne({ _id }, { x: 1, y: 2, z: 3 }, { upsert: true })
    const findResult   = await vectors.findOne({ }) // omit

    console.log(_id)         // ObjectID(620ca8968d741e4d0099b507)
    console.log(findResult)  // {
                             //      x: 1,
                             //      y: 2,
                             //      z: 3,
                             //      _id: { _bsontype: 'ObjectID', id: 'b\f¨\x96\x8Dt\x1EM\x00\x99µ\x07' }
                             // }                                  ^
                             //                         ObjectID is returned with the .id encoded as an escaped string
}

repro2()

Running comparative tests against MongoDB itself yields the expected behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions