13

不是一个特别强大的 Javascript 人,我在尝试更新DateMongo 中的很多对象时遇到了一些麻烦。

似乎$inc还没有为Dateobjects实现。因此,为了尝试每天增加一堆日期,我通过以下方式从 bash 调用(类似于)这个脚本mongo myScript.js

conn = new Mongo();
db   = conn.getDB('myDatabase');

var incrementDates = function() {
  db.blah.find(myQuery).forEach(function(doc) {

    db.blah.update(
       { _id     : doc._id
       , my_date : { $exists : true }
       }
     , { $set : { my_date : new Date(doc.my_date.getTime() + 86400000) }}
    );

  });
}

incrementDates();

基本思想似乎在 mongoDB shell 中运行良好:

> var doc = db.blah.findOne(myQuery)
> doc.my_date
ISODate("1962-11-02T23:00:00Z")
> new Date(doc.my_date.getTime() + 86400000);
ISODate("1962-11-03T23:00:00Z")

但在脚本中不是很好:

TypeError: doc.my_date has no properties

所以我认为我正在尝试调用getTime某个null地方,即使我的更新中的查询应该只返回my_date存在的文档。

关于这里发生了什么的任何想法?更重要的是:有没有更好的方法来做到这一点?

4

3 回答 3

14

从 开始Mongo 4.2db.collection.update()可以接受一个聚合管道,最后允许根据自己的值更新一个字段;从而避免低效的 find/foreach 模式。

此外,您正在查看$inc添加一天的运算符,但现在我们可以使用聚合管道作为更新,$add可以使用运算符:

// { "date" : ISODate("2020-04-05T07:14:17.802Z"), "x" : "y" }
db.collection.updateMany(
  { date : { $exists : true } },
  [{ $set: { date: { $add: ["$date", 24*60*60000] } } }]
)
// { "date" : ISODate("2020-04-06T07:14:17.802Z"), "x" : "y" }
  • 第一部分{ date : { $exists : true } }是匹配查询,过滤要更新的文档(在我们的例子中,所有文档都有该date字段)。

  • 第二部分[{ $set: { date: { $add: ["$date", 24*60*60000] } } }]是更新聚合管道(注意方括号表示使用聚合管道)。$set是一个新的聚合运算符和 的别名$addFields。然后可以在$set阶段内使用任何聚合运算符;在我们的例子$add中,现有日期和以毫秒为单位的一天表示之间的简单连接。

于 2020-04-05T07:32:53.480 回答
12

问题是我的$exists查询(显然,第二次查看)在错误的位置。正在退回的文件肯定不包括my_date.

这是修补后的功能,它按预期工作。

var incrementDates = function() {
  db.blah.find({ ... , my_date : { $exists : true } ).forEach(function(doc) {
    db.blah.update(
       { _id     : doc._id }
     , { $set : { my_date : new Date(doc.my_date.getTime() + 86400000) }}
    );
  });
}
于 2013-09-12T20:31:21.707 回答
0

从 开始,这是新聚合运算符Mongo 5.0的一个很好的用例:$dateAdd

// { "date" : ISODate("2020-04-05T07:14:17.802Z"), "x" : "y" }
db.collection.updateMany(
  { date : { $exists : true } },
  [{ $set: { date: { $dateAdd: { startDate: "$date", unit: "day", amount: 1 } } } }]
)
// { "date" : ISODate("2020-04-06T07:14:17.802Z"), "x" : "y" }
  • 第一部分{ date : { $exists : true } }是匹配查询,过滤要更新的文档(在我们的例子中,所有文档都有该date字段)。

  • 第二部分,通过将 ( ) ( ) ( ) 添加到( ) 来[{ $set: { date: { $dateAdd: { startDate: "$date", unit: "day", amount: 1 } } } }]更新date字段的值。$dateAdd1amountdayunit$datestartDate

于 2021-06-15T20:02:00.323 回答