使用Mongo上$ set中查询字段的值

时间:2015-12-04 10:26:11

标签: mongodb mongodb-query

我需要将所有非日期类型(ISO字符串,unix时间戳...)转换为js Date对象。那么有没有办法在Mongo中修改字段的值?我正在考虑$inc的问题 - 因为它修改了当前的值。

例如:在“projects”集合中给出以下doc结构:

{
  _id: '123456',
  created: '1449224127049',
  name: 'My document',
  ...
}

有没有办法做类似的事情:

db.projects.update(
  {created: {$not: {$type: 9} } },
  {$set: {created: new Date( ??? ) } },
  {multi: true}
);

1 个答案:

答案 0 :(得分:2)

可悲的是,$ operator仅适用于数组。

但是,这就是我的做法。

选择文件

为了只获取不是日期的记录,我们必须匹配每个文档中created的{​​{1}},并仅返回created上没有日期类型的文档1}}。这可以通过

来实现
db.projects.find({"created":{ $not:{ $type:9 }}})

我们希望在这里获得最高的选择性,只返回我们真正需要处理的文档,因为以下步骤相当昂贵。

创建日期

接下来,我们需要迭代返回的文档并相应地设置created字段。但是,我们遇到了一个问题,因为我们不能简单地将自纪元以来的秒数传递给Date()。因此,您需要根据所拥有的内容实现解析逻辑。让我们来看看问题的一个例子。

在mongo shell中

new Date('1449224127049')

返回

ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ")

这里的问题是我们需要实现一个不容易实现的解析逻辑,因为parseInt("2015-12-04T11:27:36.806Z")很高兴地返回2015。这个解析逻辑可能变得相当复杂而且有点不合适但是,您需要根据自己的需求和数据来实施此答案。

更新文件

使用[批量操作] [mongo:bulk]可以非常轻松地实现更新文档并获得良好的性能。基本上,你排队"排队"操作。这里的缺陷是写回完整的文档,这可能会干扰其他写操作。因此,我们需要在$set字段上明确使用created,以尽量减少操作的影响。

全部放在一起

举个例子,这是你如何实现目标

function parseDate(value){
  // This needs to be HEAVILY expanded
  var intValue = parseInt(value);
  if( isNaN(intValue) ){
    return;
  }
  return new ISODate(intValue);
}

var bulk = db.projects.initializeUnorderedBulkOp();

var docs = db.projects.find({"created":{ $not:{ $type:9 }}});
var updated = 0;
docs.forEach(
  function(doc){
    var date = parseDate(doc.created);
    if ( typeof date === "undefined" ) {
      return;
    } else {
      bulk.find({"_id":doc._id}).update({$set:{"created":date}});
      updated++;
    }
    // Batch size is 1000 anyway, and a status is nice.
    if (updated % 1000 == 0){
       print("Updated: " + updated);
       bulk.execute();
       // We can not reuse an executed bulk
       bulk = db.projects.initializeUnorderedBulkOp();
    }
  }
)
// Execute the remainder of documents
bulk.execute()

一些注释

  • 请不要对数据执行任何操作:在尝试任何操作之前进行备份。以错误的方式修改数据可能会导致数据丢失或精度下降。

  • 我(Markus)会将其发布为$type,以便其他人可以更自由地编辑我公认的hacky JS - 我简直不太喜欢JS wiz(恰恰相反)。< / p>

  • 也许日期解析可以通过第三方库来实现。