设置字段如果不存在,则推送到数组,然后返回文档

时间:2016-03-15 00:13:01

标签: node.js mongodb mongodb-query

我希望在一次操作中执行此操作,只需点击数据库一次......但我不知道api是否可能.......

我想要的是:

  1. 按ID(总是存在)找到文档
  2. 添加对象(如果该对象尚不存在){ dayOfYear: 3, dataStuff: [{time: Date(arg), data: 123] }
  3. {time: Date(arg), data: 123] }推送到dataStuff数组
  4. 返回修改后的文档
  5. 我按照

    的方式制作了一些东西
      return this.collection.findOneAndUpdate(dataDoc,
        { $set: { dayOfYear: reqBody.dayOfYear ,
          $addToSet: { dataStuff: { time: Date(reqBody.date), data: reqBody.data } 
        }
    

    但没有成功

2 个答案:

答案 0 :(得分:2)

更新对象需要每个原子操作的“单独”顶级键:

return this.collection.findOneAndUpdate(
  dataDoc,
  {
      "$set": { dayOfYear: reqBody.dayOfYear },
      "$addToSet": { 
          "dataStuff": { "time": Date(reqBody.date), "data": reqBody.data  } 
      }
  },
  { "returnOriginal": false }
)

使用核心API中的.findOneAndUpdate(),您还需要将"returnOrginal"选项设置为false才能返回修改后的文档。使用mongoose API时,它会改为{ "new": true }

在这种语法中,两个调用都返回一个“Promise”来解决,而不仅仅是一个直接的响应。

答案 1 :(得分:1)

如果要检查整个对象是否存在,则必须比较所有属性,例如

this.collections.update({
  _id: dataDoc,
  dayOfYear: {
    $ne: reqBody.dayOfYear
  },
  dataStuff: {
    $elemMatch: {
      time: {
        $ne: Date(arg)
      },
      data: {
        $ne: reqBody.data
      }
    }
  }
}, {
  $set: {
    dayOfYear: reqBody.dayOfYear,
  },
  $addToSet: {
    dataStuff: {
      time: Date(arg),
      data: reqBody.data
    }
  }
});

这样,您可以确保始终更新一个或零个集合项。第一个参数是不返回任何元素或单个元素的查询(因为_id存在),如果返回一个元素,则会更新。我相信,这正是你所需要的。