SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
805 stars 171 forks source link

BulkWrite issue..cant pass array of documents' properties. #164

Closed genxlogics closed 7 years ago

genxlogics commented 7 years ago

Hi All, i am trying to use PATCH to bulkwrite. so in the collection i got multiple documents to update, i know there identifiers and their one property that needs to be updated. issue is documents will have different value for that property to be updated.

how do i do that? i get either 207 response (Multi status) or Restheart reports the error saying "json document is expected". i cant pass the array.

please help !!

ujibang commented 7 years ago

bulk PATCH modifies all documents matching the filter query parameter with the passed data, e.g.

PATCH /db/coll/*?filter={"num": {"$gt": 10}} {"num": {"$inc": 1}}

modifies all documents whose num property is greater than 10, incrementing num by 1

you cannot pass an array.

if you want to modify documents passing an array use POST

POST /db/coll [ { "_id": 1, {"num": {"$inc": 1}}}, { "_id": 2, {"num": {"$inc": 1}}} ]

increments the num property of the documents with _id 1 and 2

genxlogics commented 7 years ago

Thanks @ujibang ,

so with POST i can use the modify operators and just change the properties i want, keeping rest of the document intact?

ujibang commented 7 years ago

on version 3.0 (in beta) yes, not sure about 2.x...

genxlogics commented 7 years ago

hi @ujibang , it doesnt work for me, when i POST the array as below, it creates two new documents for me.

[ { "emp-id":"1", "$set":{ "emp-name":"EMP1" } }, { "emp-id":"2", "$set":{ "emp-name":"EMP2" } }

]

ujibang commented 7 years ago

You need to include the _id to match documents

genxlogics commented 7 years ago

@ujibang thanks a lot. that works.

but it also inserts a new document if _id isnt present. is there a way that i can force Restheart to POST with upsert : false

ujibang commented 7 years ago

restheart write requests have all upsert semantic.

for not bulk request, the checkEtag query paramter can be used to have it not creating new documents, read more here and here

However this trick is not possible for bulk requests.

I created a new feature in our backlog to add upsert=false qparam, see https://softinstigate.atlassian.net/browse/RH-215

genxlogics commented 7 years ago

Thanks a lot @ujibang . much appreciated !!

genxlogics commented 7 years ago

@ujibang , i am trying to set the multiple properties of a document through POST as below

POST /transactional/tempreq { "_id":"1" "$set":{"prop1":"val111","prop2":"val211"} }

what it is doing is that it removes all other existing properties of the document. so no new document has only two properties.

when i use PATCH it just updates something else at i dont know where

PATCH /transactional/tempreq { { "_id":"1", "$set":{"prop1":"val111","prop2":"val211"} } }

i need to update multiple properties and keep other things intact. please help !!

ujibang commented 7 years ago

hi @genxlogics

if you have to perform different updates of several documents in one shot the way to go is bulk POST (bulk updates only modified the passed properties)

POST /db/coll 

[
 {"_id": 1, "prop": a},
 {"_id": 2, "prop": b},
 {"_id": 3, "prop": c}
]