2015-12-11 38 views
1

問題:我目前擁有包含100,000個文檔的mongo集合。每個文件有3個字段(_id,名稱,年齡)。我想爲每個名爲hashValue的文檔添加第4個字段,它存儲每個文檔名稱字段的md5哈希值。將md5哈希值添加到mongo集合

我目前可以通過mongo shell或通過Mongoose ODM與我的集合進行交互,作爲nodeJS應用程序的一部分。

可能的解決方案:

  1. 使用貓鼬/的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() 
    }); 
  • 使用蒙戈殼牌 - 幾乎與上面相同,並且我實現類似上述語法會工作。唯一的問題是我不知道如何在mongo shell中創建md5哈希。但是我能夠遍歷每個文檔並添加一個字段。

  • (可能的解決方法) - 這樣做的目標是能夠基於名稱值的md5散列進行查詢。我相信mongo允許你創建一個散列索引(link here)。唯一的問題是,我找不到任何人使用這個查詢的例子(似乎只用於分片),我不知道這是否會在以後工作。 (例如:我想MD5哈希我從用戶那裏收集的名稱,然後查詢我的蒙戈集合,看看我能找到MD5哈希的散列值字段)

  • 回答

    8

    Javascript已經擁有名爲hex_md5的md5哈希函數。它也可以在mongo控制檯中使用。

    > hex_md5('john') 
    527bd5b5d689e2c32ae974c6229ff785 
    

    你的情況,因此及時更新記錄您可以使用控制檯蒙哥下面的代碼片段:

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

    這適用於mongo控制檯中的更新。如果需要用貓鼬進行更新,請參閱下面的答案。 – user2263572

    1

    您可以通過光標在貓鼬迭代使用streams並使用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

    我閱讀文檔,這似乎是在正確的軌道上。 bulk.find({ '_ ID':el._id})更新({$集:{名稱:哈希}})。返回一個錯誤「TypeError:無法讀取未定義的屬性'find'。但總體而言,這條道路是一個很好的文件記錄解決方案。 – user2263572

    +0

    修復了錯誤。我們需要先建立連接。 –

    0

    我個人並不喜歡去與選項3(即,可能的解決方法)。拖拽的原因 - 1.查詢數據時,我們必須確保應用程序使用相同的散列函數,並以與Mongo DB相同的方式導出散列值。我認爲Mongo DB使用MD5並只考慮前64位的散列。我看到的缺點是應用程序被綁定到MongoDB哈希的內部實現,並可能在任何時候改變。

    1. 散列索引適用於點查詢(相等查詢)。但他們不支持範圍查詢(年齡> &年齡> 50),喜歡或正則表達式查詢(db.users.find({ 「名」:/ ABC /})

    有一點是不清楚的是爲什麼你想要存儲名稱列的MD5,而不是在名稱列本身上創建正常索引。可能是這將有助於得出答案。

    +0

    偉大的問題,並同意選項3.原因是,我試圖找到一種方法在名稱字段上進行高效的文本搜索。而且由於名稱字段可以包含名稱的多個部分(第一,中,後),因此大多數解決方案都需要多個查詢,集合數據結構中的更改或低效的正則表達式查詢。 – user2263572