Freewind
Freewind

Reputation: 198328

`bulkWrite` with `insertOne/updateOne` together does't work as I expected in mongodb?

I have both insertOne and updateOne in bulkWrite as following:

async function bulkWrite(users) {
  await users.bulkWrite([
    {
      insertOne: {
        document: {
          name: 'bulk-insert1',
          age: 100
        }
      },
      updateOne: {
        filter: {
          name: 'mongodb'
        },
        update: {
          $set: {
            age: 200
          }
        }
      }
    }
  ])
}

I expect it will insert a new document and update an existing document, but the result is different.

My main function:

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";

const DB_NAME = 'javascript-mongodb-bulkwrite-demo';
const COLLECTION_NAME = 'users';

async function run() {
  const mongo = await MongoClient.connect(url, {useNewUrlParser: true});
  const db = mongo.db(DB_NAME);

  await clearDb(db);

  const users = await db.createCollection(COLLECTION_NAME);

  await createUsers(users);

  await printUsers(users);

  await bulkWrite(users);

  await printUsers(users);

  await mongo.close()
}

run();

Other functions it uses:

async function clearDb(db) {
  console.log('------- clearDb --------');
  const collections = await db.collections();
  await Promise.all(collections.map(async it => {
    await it.drop();
  }));
}

async function createUsers(users) {
  console.log('------- createUsers --------');
  users.insertMany([
    {
      name: 'javascript',
      age: 10
    }, {
      name: 'mongodb',
      age: 20
    }
  ])
}

async function printUsers(users) {
  console.log('------- printUsers --------');
  await users.find().forEach(user => {
    console.log(user);
  })
}

The bulkWrite function:

async function bulkWrite(users) {
  console.log('------- bulkWrite --------');
  return await users.bulkWrite([
    {
      insertOne: {
        document: {
          name: 'bulk-insert1',
          age: 100
        }
      },
      updateOne: {
        filter: {
          name: 'mongodb'
        },
        update: {
          $set: {
            age: 200
          }
        }
      }
    }
  ])
}

Current result is like:

------- clearDb --------
------- createUsers --------
------- printUsers --------
{ _id: 5c10b6011dd87efa7feb5b47, name: 'javascript', age: 10 }
{ _id: 5c10b6011dd87efa7feb5b48, name: 'mongodb', age: 20 }
------- bulkWrite --------
------- printUsers --------
{ _id: 5c10b6011dd87efa7feb5b47 }
{ _id: 5c10b6011dd87efa7feb5b48, name: 'mongodb', age: 20 }

And I expect the last part to be:

{ _id: 5c10b6011dd87efa7feb5b47, name: 'javascript', age: 10 }
{ _id: 5c10b6011dd87efa7feb5b48, name: 'mongodb', age: 20 }
{ _id: 5c10b6011dd87efa7feb5b49, name: 'bulk-insert1', age: 100 }

I also created a demo project for this, you can clone and run it:

https://github.com/freewind-demos/javascript-mongodb-bulkwrite-demo

(I locked current code to issue branch)

Upvotes: 3

Views: 4708

Answers (1)

Alex Blex
Alex Blex

Reputation: 37048

It's just a typo. You missed a pair of curly brackets between bulk operations.

It should be:

  const res = await users.bulkWrite([
    {
      insertOne: {
        document: {
          name: 'bulk-insert1',
          age: 100
        }
      } 
    }, { 
      updateOne: {
        filter: {
          name: 'mongodb'
        },
        update: {
          $set: {
            age: 200
          }
        }
      }
    }
  ]);

Upvotes: 3

Related Questions