I have the following document :
{
"recordKey": "FOO",
"channels": [{
"id": "CH1",
"blocks": []
}, {
"id": "CH2",
"blocks": []
}]
}
In my current use case, I'm doing two requests with addToSet
operator for adding new blocks for the channel CH1
or CH2
For example for the channel CH1
, I'm doing this:
selector =
{
"$and" : [ {
"recordKey" : "FOO"
}, {
"channels.id" : "CH1"
} ]
}
addChunkRequest = "$addToSet" : {
"channels.$.blocks" : {
"$each" : [ {
"startime" : 101000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f1",
"nsamples" : 1000
}
query1 = db.collection.update(selector, update)
I'm doing the same think for the channel CH2. Now I want to group the two requests in one request. How can I achieve that ?
答案 0 :(得分:2)
Well you cannot of course "update multiple array elements in the one operation", because that is just not presently allowed and a restriction of the positional $
operator.
What you "can" do however is use Bulk Operations to issue "both" operations in a "single request" to the server:
var data = [
{
"channel": "CH1",
"blocks": [{
"startime" : 101000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f1",
"nsamples" : 1000
}]
},
{
"channel": "CH2",
"blocks": [{
"startime" : 202000000,
"blockType" : "DATA",
"fileLoc" : "/tmp/f2",
"nsamples" : 2000
}]
}
]
var ops = data.map(d => ({
"updateOne": {
"filter": { "recordKey": "FOO", "channels.id": d.channel },
"update": {
"$addToSet": { "channels.$.blocks": { "$each": d.blocks } }
}
}
});
db.collection.bulkWrite(ops);
So it's still "two" operations and that cannot be avoided, however it's only "one" request and response from the server, and that actually helps you quite a lot.