MongoDB Bulk.find.update()不修改数组对象,只添加新对象

时间:2016-03-22 12:31:03

标签: arrays mongodb mongodb-update

我遇到MongoDB $ set& $ -operators。我尝试修改现有的数组

我的更新方法看起来像这样(我无法获得Clojure / Monger中编写的完整副本):

    bulk.find({
            _id: 2,
            channelStatuses.channel: {$eq: "BAR"}
    }).update({
            $set: {"channelStatuses.$.status": "error" }
    });

我的数据看起来像这样:

{
  "_id" : "1",
  "channelStatuses" : [
    {
      "channel" : "FOO",
      "status" : "done"
    }
  ]
},
{
  "_id" : "2",
  "channelStatuses" : [
    {
      "channel" : "BAR",
      "status" : "done"
    }
  ]
},
{
  "_id" : "3",
  "channelStatuses" : [
    {
      "channel" : "BAZ",
      "status" : "error"
    }
  ]
},
{
  "_id" : "3",
  "channelStatuses" : []
}

所以我想要它做的是用_id = 2修改文档的channelStatuses对象的状态。

相反,它会在channelStatuses数组中创建一个新对象,文档如下所示:

    {
      "_id" : "2",
      "channelStatuses" : [
        {
          "channel" : "BAR",
          "status" : "done"
        },
        {
          "channel" : "BAR",
          "status" : ""
        }
      ]
    },

1 个答案:

答案 0 :(得分:2)

所以我发现你的查询有几个问题。

  1. 在您的文档中, $key = "...key..."; $url = "https://docs.google.com/spreadsheets/d/...key.../pubhtml"; $ch = curl_init(); // set URL and other appropriate options curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // grab URL and pass it to the browser $google_sheet = curl_exec($ch); // close cURL resource, and free up system resources curl_close($ch); $doc = new DOMDocument(); $doc->loadXML($google_sheet); $nodes = $doc->getElementsByTagName("cell"); if($nodes->length > 0) { foreach($nodes as $node) { // 2nd row is the email row. if ($node->getAttribute("row") == 2) { if (eregi("^[\.\+_a-z0-9-]+@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$", $node->nodeValue) ) { mail($node->nodeValue, "Mail Subject", "Mail Message.", "From: email@yourdomain.com"); } } } } 字段是文本值,但在查询中,您将其用作数字。

  2. 在您的查询_id无效。除非你用双引号转义,否则JSON密钥内部不能有channelStatuses.channel: {$eq: "BAR"}

  3. 您可以将.简化为channelStatuses.channel: {$eq: "BAR"}

  4. 现在尝试以下查询并查看它是否有效。

    "channelStatuses.channel": "BAR"

    它应该只更新现有字段。见下面的最终输出

    var bulk = db.doc.initializeUnorderedBulkOp();
    
    bulk.find({ 
      _id: "2", 
      "channelStatuses.channel": "BAR" 
      }).update({
                $set: {"channelStatuses.$.status": "error" }
      });
    
    bulk.execute();