Reputation: 3579
This is my final document structure. I am on mongo 3.0.
{
_id: "1",
stockA: [ { size: "S", qty: 25 }, { size: "M", qty: 50 } ],
stockB: [ { size: "S", qty: 27 }, { size: "M", qty: 58 } ]
}
I am randomly adding elements inside stockA
or stockB
collections.
I would like come up with a query which would satisfy following rules:
item
is not exist - create whole document and insert item in stock A or B
collection. item
is exist but stock A or B
collection is missing create stock
collection and add element
inside collection. item
is exist and stock
collection is exist just append element
inside collection. Question: Is it possible to achieve all that in one query? My main requirement that current insert has to be extremely fast and scalable.
If yes, could you please help me to come up with required query.
If no, could you please guide me how do I achieve requirements in fastest and cleanest way.
Thanks for any help!
Upvotes: 0
Views: 2059
Reputation: 61225
You can use the update
method with the upsert
option which will create a new document when no document matches the query criteria.
db.collection.update({ "_id": 1 },
{
"$push" : {
"stockB" : {
"size" : "M",
"qty" : 51
},
"stockA" : {
"size" : "M",
"qty" : 21
}
}
},
{ "upsert": true }
)
Upvotes: 1
Reputation: 69663
The operator you are looking for is $addToSet
or $push
in combination with upsert:true
.
Both operators can take multiple key/value pairs. It will then operate separately on each key. Both will create the array when it doesn't exist yet, and in either case will add the value.
The difference is that $addToSet will first check if an identical element already exists in the array. When performance is an issue, keep in mind that MongoDB must perform a linear search to do this. So for very large arrays, $addToSet can become quite slow.
The upsert:true
option to the update function will result in the document being created when it isn't found.
Upvotes: 2