Jee Mok
Jee Mok

Reputation: 6566

Loopback - How to use bulkUpdate method

I'm using Loopback v3 currently and wanted to upsert many records at once in a collection; I found this method bulkUpsert from the documentation (http://apidocs.loopback.io/loopback/#persistedmodel-bulkupdate) but I couldn't figure out how to make it work.

How can I create the updates array from createUpdates() method as mentioned in the documentation? Can anyone help me with a simple example of using this method?

Upvotes: 3

Views: 2833

Answers (1)

Jee Mok
Jee Mok

Reputation: 6566

There is an alternative way to do the bulkUpdate method, found in Stackoverflow MongoDB aggregation on Loopback

A mixin can be easily created and reused over the Models. My sample code of bulkUpsert mixin is below:

Model.bulkUpsert = function(body, cb) {
    try {
      Model.getDataSource().connector.connect(async (err, db) => {
        if (err) {
          return cb(err);
        }

        // Define variable to hold the description of the first set of validation errors found
        let validationErrors = '';

        // Build array of updateOne objects used for MongoDB connector's bulkWrite method
        const updateOneArray = [];

        // Loop through all body content and stop the loop if a validation error is found
        const hasError = body.some(row => {
          // Check if it is a valid model instance
          const instance = new Model(row);
          if (!instance.isValid()) {
            // A validation error has been found
            validationErrors = JSON.stringify(instance.errors);
            // By returning true we stop/break the loop
            return true;
          }

          // Remove ID in the row
          const data = JSON.stringify(row);
          delete data.id;

          // Push into the update array
          updateOneArray.push({
            updateOne: {
              filter: { _id: row.id },
              update: { $set: Object.assign({ _id: row.id }, data) },
              upsert: true
            }
          });

          // No validation error found
          return false;
        });

        // Check if a validation error was found while looping through the body content
        if (hasError) {
          return cb(new Error(validationErrors));
        }

        // No validation data error was found
        // Get database collection for model
        const collection = db.collection(Model.name);
        // Execute Bulk operation
        return collection.bulkWrite(updateOneArray, {}, (err, res) => {
          // Check if the process failed
          if (err) {
            console.err('The bulk upsert finished unsuccessfully', err);
            return cb(err);
          }

          // Check if there were errors updating any record
          if (res.hasWriteErrors()) {
            console.error(`The bulk upsert had ${res.getWriteErrorCount()} errors`, res.getWriteErrors());
          }

          // Finished successfully, return result
          return cb(null, {
            received: body.length,
            handled: res.upsertedCount + res.insertedCount + res.matchedCount
          });
        });
      });
    }
    catch (err) {
      console.error('A critical error occurred while doing bulk upsert', err);
      return cb(err);
    }
    return null;
  };

Ref: Mongodb query documentation

Upvotes: 3

Related Questions