将md5哈希值添加到mongo集合中

时间:2015-12-11 03:20:18

标签: node.js mongodb hash mongoose md5

问题:我目前有一个包含100,000个文档的mongo集合。每个文档都有3个字段(_id,name,age)。我想在每个名为hashValue的文档中添加第4个字段,该字段存储每个文档名称字段的md5哈希值。

我目前可以通过mongo shell或Mongoose ODM与我的集合进行交互,作为nodeJS应用程序的一部分。

可能的解决方案:

  1. 使用Mongoose / nodeJs:
  2. 我意识到这不会起作用(不相信你可以用这种方式迭代光标),但希望它能显示我想要做的事情。

    var crypto = require('crypto');
    
        MyCollection.find().forEach(function(el){
            var hash = crypto.createHash('md5').update(el.name).digest("hex");
            el.name = hash;
            el.save()
        });
    
    1. 使用mongo Shell - 几乎和上面一样,我意识到上面的语法会起作用。唯一的问题是我不知道如何在mongo shell中创建md5哈希。但我能够遍历每个文档并添加一个字段。

    2. (可能的解决方法) - 这样做的目的是能够根据名称值的md5哈希进行查询。我相信mongo允许你创建一个散列索引(link here)。唯一的问题是,我找不到任何人使用它进行查询的例子(似乎只是用于分片),我不确定这是否会在以后工作。 (示例:我想md5哈希我从用户收集的名称,然后查询我的mongo集合,看看我是否可以在hashValue字段中找到md5哈希)

3 个答案:

答案 0 :(得分:8)

Javascript已经有md5哈希函数,名为hex_md5。它也可以在mongo控制台中使用。

> hex_md5('john')
527bd5b5d689e2c32ae974c6229ff785

因此,要更新您的案例中的记录,您可以在mongo控制台中使用以下代码段:

db.collection.find().forEach( function(data){
  data.hashValue = hex_md5(data.name);
  db.collection.save(data);
});

答案 1 :(得分:1)

您可以使用streams在mongoose中迭代游标,并使用bulk更新所有记录。

mongoose.connection.on("open", function(err,conn) {
    var bulk = MyCollection.collection.initializeUnorderedBulkOp();
    MyCollection.find().stream()
        .on('data', function(el){
            var hash = crypto.createHash('md5').update(el.name).digest("hex");
            // add document update operation to a bulk
            bulk.find({'_id': el._id}).update({$set: {name: hash}});
        })
        .on('error', function(err){
            // handle error
        })
        .on('end', function(){
            // execute all bulk operations
            bulk.execute(function (error) {
                // final callback
                callback();                   
            });
        });
    });

答案 2 :(得分:0)

我个人不喜欢选择3(即可能的解决方法)。两个原因 - 1.在查询数据时,我们必须确保应用程序使用相同的哈希函数,并以与Mongo DB相同的方式,派生哈希值。我认为Mongo DB使用MD5并且仅考虑散列的前64位。我看到的缺点是应用程序与Mongo DB散列的内部实现相关联,并且可能随时发生变化。

  1. 散列索引适用于点查询(相等查询)。但它们不支持范围查询(年龄>& age> 50),或者正则表达式查询(db.users.find({“name”:/ ABC /})。
  2. 有一点不清楚的是,为什么要存储名称列的MD5而不是在名称列本身上创建普通索引。可能会有助于得出答案。