Group multi addToSet requests in a single request

时间:2017-06-15 09:48:37

标签: mongodb mongodb-query

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 ?

1 个答案:

答案 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.