2016-11-17 16 views
1

我們收集了大量的各種文本案例文件中的描述在輸入時 如的MongoDB - 更新文本正確/標題案例

Desc = 
'THE CAT" 
or 
"The Dog" 
or 
"the cow" 

我們要在標題(適當的情況下,OR)的所有一致每個單詞的首字母大寫,小寫。

"The Cat", "The Dog", "The Cow" 

創建更新查詢做質量上,而不是手動數據團隊目前在做尋找幫助。

感謝

+0

多少文件?如果沒有那麼多,你可以使用一個簡單的forEach和普通的js代碼。 –

回答

2

下面用於改變標題情況下,算法使用Array.prototype.map()方法和String.prototype.replace()方法,它返回與一些或通過替換替換的圖案的所有比賽的新字符串。 在你的情況下,replace()方法的模式將被String替換爲新替換,並將被視爲逐字字符串。

首先,在應用map()方法之前,您需要小寫並分割字符串。一旦你定義了一個實現轉換的函數,你就需要遍歷你的集合來應用這個函數的更新。使用由find()返回做循環光標cursor.forEach()方法以及循環內你就可以運行使用updateOne()方法每個文檔的更新。

對於相對小的數據集,整個操作可由以下

function titleCase(str) { 
    return str.toLowerCase().split(' ').map(function(word) { 
     return word.replace(word[0], word[0].toUpperCase()); 
    }).join(' '); 
} 

db.collection.find({}).foEach(function(doc){ 
    db.collection.updateOne(
     { "_id": doc._id }, 
     { "$set": { "desc": titleCase(doc.desc) } } 
    ); 
}); 

描述對於特別巨大的數據集處理時改進的性能,採取使用Bulk() API用於更新的優點因爲您將批量發送操作到服務器(例如批量大小爲500),因此可以批量高效地進行收集。由於您不會向服務器發送每個請求,而只會在每500次請求中發送一次請求,因此可以提供更好的性能,從而使您的更新更加高效快捷。

以下演示了這種方法,第一個示例使用了可用於MongoDB版本> = 2.6和< 3.2中的API Bulk() 3.2。它通過使用上述功能在desc字段上轉換標題來更新集合中的所有文檔。

MongoDB的版本> = 2.6和< 3.2

function titleCase(str) { 
    return str.toLowerCase().split(' ').map(function(word) { 
     return word.replace(word[0], word[0].toUpperCase()); 
    }).join(' '); 
} 

var bulk = db.collection.initializeUnorderedBulkOp(), 
    counter = 0; 

db.collection.find().forEach(function (doc) {  
    bulk.find({ "_id": doc._id }).updateOne({ 
     "$set": { "desc": titleCase(doc.desc) } 
    }); 

    counter++; 
    if (counter % 500 === 0) { 
     // Execute per 500 operations 
     bulk.execute(); 
     // re-initialize every 500 update statements 
     bulk = db.collection.initializeUnorderedBulkOp(); 
    } 
}) 
// Clean up remaining queue 
if (counter % 500 !== 0) { bulk.execute(); } 

下示例適用於新的MongoDB 3.2版,其具有自deprecatedBulk() API和提供一種使用的API的一個較新的組bulkWrite()

MongoDB版本3。2以上

var ops = [], 
    titleCase = function(str) { 
     return str.toLowerCase().split(' ').map(function(word) { 
      return word.replace(word[0], word[0].toUpperCase()); 
     }).join(' '); 
    }; 

db.Books.find({ 
    "title": { 
     "$exists": true, 
     "$type": 2 
    } 
}).forEach(function(doc) { 
    ops.push({ 
     "updateOne": { 
      "filter": { "_id": doc._id }, 
      "update": { 
       "$set": { "title": titleCase(doc.title) } 
      } 
     } 
    }); 

    if (ops.length === 500) { 
     db.Books.bulkWrite(ops); 
     ops = []; 
    } 
}) 

if (ops.length > 0) 
    db.Books.bulkWrite(ops); 
+0

謝謝Chridam。 已經嘗試過,但必須缺少一些東西。我在MongoDb 3.2.10 我的集合被命名爲「書籍」,所以在腳本中用「書籍」取代了「集合」。 使用MongChef,粘貼的腳本轉換成Inellishell,跑和得到: 2016-11-18T09:46:57.730 + 0000ÈQUERY [線程1]類型錯誤:STR未定義: 標題字符@(殼):3:1 @(shell):6:20 [email protected]/mongo/shell/query.js:488:1 @(shell):1:1 2016-11-18T09:46:57.736 + 0000 E QUERY [thread1] SyntaxError:預期表達式,腳本@(shell)結束:1:19 – MarkM

+0

您使用的代碼是哪種?另外,請確保在文檔中有一個「desc」字段,或者將代碼中的「desc」實例替換爲模式中的實際** description **字段,否則將失敗。 – chridam

+0

我用你的帖子底部的代碼3.2 是的,我改變了「desc」字段中的2個景點,這是我的dB字段名稱... 對不起。現在只是得到: TypeError:字[0]未定義 – MarkM