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

问题描述 投票:0回答:4

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

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

可能的解决方案:

  1. 使用 Mongoose/nodeJs:

我意识到这是行不通的(不相信你可以以这种方式迭代游标),但希望它能显示我正在尝试做的事情。

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 允许您创建散列索引(链接此处)。唯一的问题是,我找不到任何人使用它进行查询的示例(似乎仅用于分片),并且我不确定以后是否会起作用。 (示例:我想对从用户那里收集的名称进行 md5 哈希,然后查询我的 mongo 集合,看看是否可以在 hashValue 字段中找到该 md5 哈希)

node.js mongodb hash mongoose md5
4个回答
18
投票

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
投票

您可以使用 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();                   
            });
        });
    });

0
投票

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

  1. 哈希索引非常适合点查询(相等查询)。但它们不支持范围查询(年龄>&年龄> 50),喜欢或正则表达式查询(db.users.find({“name”:/ABC/})。

不清楚的一件事是为什么要存储名称列的 MD5,而不是在名称列本身上创建普通索引。也许这将有助于找到答案。


0
投票

截至目前(版本 7),您可以在 $function 聚合中使用 hex_md5:

$addFields: {
  _md5: {
    $function: {
      body: function(token1, currency) {
        return hex_md5(token1 + "_" + currency);
      },
      args: ["$_token1", "$_currency"],
      lang: "js"
    }
  },
}
© www.soinside.com 2019 - 2024. All rights reserved.