MongoDB Shell脚本:更新所有字段名中含有空格的字段名。

4
使用MongoDB shell script 3.2,如何更新所有字段名称中带有空格的字段并将其替换为下划线?
{
"Some Field": "value",
"OtherField" :"Value",
"Another Field" : "Value"
}

请根据以下方式更新上述文档:
{
"Some_Field": "value",
"OtherField" :"Value",
"Another_Field" : "Value"
}

用类似以下代码可以进行字段重命名

db.CollectionName.update( { _id: 1 }, { $rename: { 'nickname': 'alias', 'cell': 'mobile' } } )

这里的挑战在于筛选器,如何设计一个筛选器以应对字段名称中存在空格的情况。


您无法更新字段名称。您可以添加一个新的字段并更改名称,以您想要的方式。然后删除旧字段。 - Shrabanee
我能不能做一些类似于查找带有空格的字段,设置新字段(与下划线相同),并删除带有空格的字段的操作? - HaBo
@Shrabanee,我该如何编写查询来查找所有具有带空格字段名称的字段或文档? - HaBo
我认为这也不可能。我从未尝试过这样的查询。也许你需要手动实现这个功能。 - Shrabanee
看起来有类似这样的东西 https://dev59.com/1lnUa4cB1Zd3GeqPeNBR - HaBo
我不确定如何使用问题中的解决方案。从未使用过这样的查询。尝试一下,看看是否有效。 - Shrabanee
2个回答

2

这需要一个两步走的方法。首先,您需要一种机制来获取集合中所有包含空格的键的列表。一旦获取了列表,就可以构建一个对象,将这些键映射到它们重命名后的值。然后,您可以将该对象用作您的$rename操作员文档。考虑使用mapReduce来获取带有空格的键的列表。

以下mapReduce操作将使用过滤后的键作为_id值填充一个单独的集合:

mr = db.runCommand({
    "mapreduce": "CollectionName",
    "map": function() {
        var regxp = /\s/;
        for (var key in this) { 
            if (key.match(regxp)) {
                emit(key, null); 
            }
        }
    },
    "reduce": function() {}, 
    "out": "filtered_keys"
})

为获取所有的空格键列表,请在结果集上运行去重操作(distinct):
db[mr.result].distinct("_id")
["Some Field", "Another Field"]

现在,根据上面的列表,您可以通过创建一个对象并在循环中设置其属性来组装更新文档。通常,您的更新文档将具有以下结构:
var update = {
    "$rename": {
        "Some Field": "Some_Field",
        "Another Field": "Another_Field"        
    }
}

因此
var update = { "$rename": {} };
db[mr.result].distinct("_id").forEach(function (key){
    update["$rename"][key] = key.replace(/ /g,"_");
});

你可以在更新中使用它们:

db.CollectionName.update({ }, update, false, true );

1
key.replace(" ", "_") 只会替换第一个空格,可能会有像 "Some Field Value" 这样的字段。 - HaBo
@HaBo 感谢您的注意,我已经在replace()方法中更新了一个全局范围的正则表达式。 - chridam
1
欢迎您,您需要将此更改为key.match(regxp),其中r应替换为regxp。 - HaBo
哦,太多粗心的错误了:P 再次感谢你发现这些。 - chridam

1

感谢 @chridam 的出色查询。

为了运行查询,需要进行一些小的更改,完整可工作的查询。

mr = db.runCommand({
    "mapreduce": "MyCollectionName",
    "map": function() {
        var regxp = /\s/;
        for (var key in this) { 
            if (key.match(regxp)) {
                emit(key, null); 
            }
        }
    },
    "reduce": function() {}, 
    "out": "filtered_keys"
})

db[mr.result].distinct("_id")

var update = { "$rename": {} };
db[mr.result].distinct("_id").forEach(function (key){
    update["$rename"][key] = key.replace(/\s+/g, "_");
});

//print(update)

db.MyCollectionName.update({ }, update, false, true );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接