如果存在记录,则更新即使不创建新记录

时间:2018-02-07 17:41:17

标签: mongodb meteor

{
  "_id": "W4ZZxraDXGj3FtJek",
  "name": "Rust",
  "description": "new programming language by google",
  "organization": "rYefzmKDCoqKJQmeA",
  "status": "active",
  "dateAdded": "2018-02-07T13:51:31.564Z",
  "members": [
    {
      "id": "6BuSTu6GZybkmozWW",
      "role": "manager",
      "hours": "",
      "dateAdded": "2018-02-07T15:13:30.654Z",
      "reports": [
        {
          "date": "2018-02-06T12:39:32.118Z",
          "hours": "19123"
        },
        {
          "date": "2018-02-05T12:39:32.118Z",
          "hours": "19123"
        }
      ]
    },
{
      "id": "aFJlejSTu6erawlkjeru",
      "role": "manager",
      "hours": "",
      "dateAdded": "2018-02-07T15:13:30.654Z",
      "reports": [
        {
          "date": "2018-02-06T12:39:32.118Z",
          "hours": "19123"
        }
        }
      ]
    }
  ]
}

我有这样的系列。我想要做的是按ID搜索项目,搜索单个成员并根据日期属性查找特定报告。如果找到,我想更新时间。如果不是,我想创建一个新的报告对象。

我正在创建一个测试应用来学习流星。目前是meteor和NoSQLs的新手(mongoDB)

 Projects.update({
       _id: projId,
       "members.id": memberId
    }, { 
       $set: { "members.$.hours": hours } 
      });

到目前为止我所做的是更新“小时”和“小时”。但是我添加了一个新的报告'具有嵌套对象的字段。

2 个答案:

答案 0 :(得分:2)

MongoDB有一个upsert概念,并在更新函数的选项中设置:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

您很可能会为您的案例找到$setOnInsert运算符,因为默认情况下它只会设置您指定的更新值,如果您想在插入中插入其他项而不是更新您可以使用此运算符。可以在此处找到更多信息 - https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/

查看更多阅读 - https://docs.mongodb.com/manual/reference/method/db.collection.update/#upsert-option

答案 1 :(得分:1)

你可以走简单路线.. 使用findOne获取记录。

const p = Projects.findOne({_id:id});

//If record exists update or insert.

if(p){
Projects.update({_id:id},{$set:{abcd:defg}});
}else{
Projects.insert({abcd:defg});
}

每一步都有控制权。 findOne查询非常有效。