Start a new topic

Business Logic findAndModify creates duplicate records.

Recently, my older Business logic script started creating duplicate records.

On create, it create a record. On update, it keeps updating a different record. So, it only create two similar records with same _id.


Here is the pre-save script:


 

function onPreSave(request, response, modules) {
  var method = request.method;
  var collectionName = request.collectionName;
  var requestId = request.body._id;
  modules.logger.info("Request ID: "+requestId);
  if ((method == "PUT" || method == "POST") && requestId && typeof requestId != 'undefined') {
    var itemsList = request.body.items;
    var collectionAccess = modules.collectionAccess;
    modules.logger.info("Request ID: "+request.body);
    collectionAccess.collection(collectionName).findAndModify({_id:requestId},null, { $set: { _id: requestId, _acl: request.body._acl, _kmd: request.body._kmd,title: request.body.title}, $addToSet: { items: { $each: itemsList } }  }, {new: true, upsert: true},function (err, doc) {
      if (err) {
        response.body.debug = err;
        response.complete(500);
      } else {
        response.body = modules.kinvey.entity(doc);
        response.complete(200, response.body);
      }
    });
  } else {
    modules.logger.info("Request not ID: "+requestId);
    response.continue();
  }
}

 


Hi,


Can you tell me what you are trying to achieve with this BL script?


The _id attribute is expected/implemented to be unique in Kinvey collections. Are you sure you are seeing duplicate records with same _ids?


Also, you shouldn't be calling findAndModify/response.complete inside onPreSave on the same collection.



Regards,

Wani

Kinvey Support

Hey,


I think I am using it for the wrong reasons. Just to get your opinion, here is the scenario where I need some custom logic. It would help if you can let me know of the correct approach.


Lets say:

I have a collection of "Baskets". Each "Basket" document has an attribute called "items" which contains array of items like: ["apple","banana"].

I want to use Business logic to ensure that any new items present in the "items" field is added to the current list in the "bucket".


So, if a user updated a bucket with ["apple","oranges","plums"], the collection document can be updated with ["apple","banana","oranges","plums"]. I've used an array to store items as the order is important.


Any other way I can do this? I am now thinking of custom endpoints. I am using iOS SDK, so I would like to avoid anything outside the iOS APIs.


Thanks,


D



Hi,


Let's say you fetched a basket object from Baskets collection. It has items value as ["apple","banana"]. And then, you pushed new entries to items and the updated items is now ["apple","banana","oranges","plums"]. While pushing to items array, you will have to check if that element is already present (e.g. "apple").


To push these changes to the backend, all you need to do is save the basket object to using http://devcenter.kinvey.com/ios/guides/datastore#Saving


You don't need to use Business Logic scripts at all. All this can happen inside your iOS application code.


Let me know if this helps.



Regards,

Wani

Sorry that I did not mention that the "Basket" is shared amongst users.

Tf there are two users, with following sequence of transactions:


- User A fetched items: ["apple","banana"]

- User B fetched items: ["apple","banana"]

- User A inserts ["orange"] so items is: ["apple","banana","orange"]

- User B inserts ["plum"] so items is: ["apple","banana","plum"]


In the database, I still want ["apple","banana","orange","plum"]

Login or Signup to post a comment