如何正确增加mongoDB中的许多日期?

jto*_*bin 9 javascript mongodb

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

似乎$inc尚未实现Date对象.所以,为了尝试在一天之内碰到一堆日期,我从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();
Run Code Online (Sandbox Code Playgroud)

基本思想似乎在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")
Run Code Online (Sandbox Code Playgroud)

但在脚本中不太好:

TypeError: doc.my_date has no properties
Run Code Online (Sandbox Code Playgroud)

所以我认为我试图getTimenull某处调用,即使我的更新中的查询应该只返回my_date存在的文档.

关于这里发生了什么的任何想法?更重要的是:有更好的方法吗?

Xav*_*hot 13

从 开始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" }
Run Code Online (Sandbox Code Playgroud)
  • 第一部分{ date : { $exists : true } }是匹配查询,过滤要更新的文档(在我们的例子中所有文档都具有该date字段)。

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


jto*_*bin 9

问题是我的$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) }}
    );
  });
}
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 5

从 开始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" }
Run Code Online (Sandbox Code Playgroud)
  • 第一部分{ date : { $exists : true } }是匹配查询,过滤要更新的文档(在我们的例子中是所有具有该date字段的文档)。

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