Skip to content

How to use Mongo's findOneAndUpdate. #4258

Closed

Description

@majidhassan

Hello,

I'm trying to update a single object atomically as it could be written to from multiple users at - more or less - the same time. This should be done using collection.findOneAndUpdate. Is there any way I can use this within Parse, without having to use Mongo's NodeJS client?

Activity

  1. flovilmart commented on Oct 23, 2017

    @flovilmart
    Contributor

    you could use it via cloudCode, and maintain your own connection to mongoDB and run those operations atomically.

    Note that many operations are already atomic (like increment, addUnique etc...)

  2. majidhassan commented on Oct 26, 2017

    @majidhassan
    Author

    Hey @flovilmart,

    I already run my own connection from cloud code. My question was, whether there's a "parse" way to do it, or whether I have to implement it using the NodeJS Mongo client.

    Also, regarding increment and other functions, I've tried them, and - unlike findOneAndUpdate - they don't force a write lock on the collection / document when I tried them.

  3. oallouch commented on Jan 21, 2018

    @oallouch
    Contributor

    same question here
    I guess I'll go the mongo-driver-way.

  4. yomybaby commented on Feb 6, 2018

    @yomybaby
    Contributor

    On the mongodb, findOneAndUpdate of adapter uses findAndModify of mongoDB collection. (code)

    findAndModify method is also atomically update. (docs)

    So I use this way on cloud code :

    Parse.Cloud.define('borrowBookFromLibrary', function(request, response) {
      const { amount, bookId } = request.params;
      
      const {
        AppCache
      } = require('parse-server/lib/cache'); // this refrenese only in cloud cloud
      const app = AppCache.get(process.env.APP_ID);
      
      if(!amount || amount <= 0 || ! bookId) { // some validation
        response.error('invalid');
      }
      const schema = { // you don't have to write all specifics here, but have to have fields object.
        fields: {
        }
      };
      
      const query = {
        objectId: bookId,
        available: {
          $gte: amount
        }
      };
    
      const update = {
        available: {
          "__op": "Increment",
          "amount": amount * -1
        },
        history: {
          "__op": "Add",
          "objects": [{
            by: 'James',
            requestDate: new Date()
          }]
        }
      };
      
      app.databaseController.adapter.findOneAndUpdate(
        'BookLibrary',
        schema,
        query,
        update
      ).then((result) => {
        if (result) {
          response.success({ success: true });
        } else {
          response.error({ error: true })
        }
      });
    });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions