MongoDB - 将文本更新为Proper / title Case

时间:2016-11-17 08:38:19

标签: mongodb

我们在输入描述时会收到大量带有各种文本案例的文档 例如

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

我们希望在标题(或正确的情况)中使所有字符保持一致,其中每个单词的第一个字母为高位,其余为小写字母。

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

寻求协助创建更新查询来实现质量,而不是手动,因为数据团队目前正在做。

感谢

1 个答案:

答案 0 :(得分:2)

下面改变标题案例的算法使用Array.prototype.map()方法和String.prototype.replace()方法,该方法返回一个新的字符串,其中一个或所有匹配的模式被替换替换。 在您的情况下,replace()方法的模式将由String替换为新的替换,并将被视为逐字字符串。

首先,在应用map()方法之前,您需要小写并拆分字符串。定义实现转换的函数后,您需要迭代集合以使用此函数应用更新。使用 cursor.forEach() 返回的光标上的 find() 方法进行循环,然后在循环内使用每个文档运行更新 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版本中的 Bulk() API> = 2.6和< 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(); }

下一个示例适用于自deprecated Bulk() API以来的新MongoDB版本3.2,并使用 {{3}提供了一套更新的api }

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);