Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.92k stars 3.84k forks source link

{useNewUrlParser: true, useUnifiedTopology: true} causes MongoError: Must run update to shard key field in a multi-statement transaction or with retryWrites: true #9393

Open amit777 opened 4 years ago

amit777 commented 4 years ago

Do you want to request a feature or report a bug? bug

What is the current behavior? updateOne operation succeeds

If the current behavior is a bug, please provide the steps to reproduce.

Trying to update a document's shard key, my code below works when useNewUrlParser is not set. The shard key is {domain: 1, sender: 1 ,objecttype:1 }

const mongoose = require('mongoose');
var Schema = mongoose.Schema;

var activitySchema = new Schema({
domain: String,
sender: String,
objecttype: String,
hash: String,
foo: String
}, {collection: 'activity'});

var conn;
var connect = function () {
// mongos is running on localhost 27018. It points to a sharded cluster
const dburl = 'mongodb://localhost:27018/test_db';
const dbOptions = {"native_parser":true,
    "useUnifiedTopology":true,
 // "useNewUrlParser":true,
  "poolSize":10
  };
};

connect();

conn.on('connected', async () => {
  console.log('connected to mongo');
  conn.model('Activity', activitySchema);
  try{
    const Activity = conn.model('Activity');

  var res = await Activity.collection.updateOne(
  { domain: null, sender: null, objecttype: 'chair', hash: 'random1'}, 
  { '$set': { domain: 'example.com', sender: 'joe@example.com', objecttype: 'chair', foo: 'bar'}
} );

  console.log(res);
  }
  catch(e){
    console.log('caught e='+e);
  }
});

What is the expected behavior? The document should update without error

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version. node 14.8.0 mongoose 5.10.3 mongodb 4.2.9

amit777 commented 4 years ago

I've tried adding "?retryWrites=true" to my db connection string, but it doesn't work.

If i use mongo shell to connect with --retryWrites, the updateOne() query works. If I connect to mongo shell without --retryWrite, I get the same "MongoError: Must run update to shard key field in a multi-statement transaction or with retryWrites: true"

So it seems for some reason retryWrites may be getting set to false somewhere when I have useNewUrlParser.

amit777 commented 4 years ago

after a bunch of testing, the issue actually seems to happen when both useNewUrlParser AND useUnifiedTopology are both true.

vkarpov15 commented 4 years ago

This looks like an issue with the MongoDB driver, I wasn't able to resolve it but I opened up an issue on the MongoDB node driver jira with more information: https://jira.mongodb.org/browse/NODE-2827?jql=project%20%3D%20NODE%20AND%20resolution%20%3D%20Unresolved%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC

As a workaround, you can disable useUnifiedTopology for now.