Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
sinclairzx81 opened this issue Feb 16, 2022 · 1 comment
Open

Comments

@sinclairzx81
Copy link

sinclairzx81 commented Feb 16, 2022

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.

@giovanni-bertoncelli
Copy link

I have the same issue, the _id returned by searching for the upserted item is null.

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

No branches or pull requests

3 participants