我在mongodb中有一个字符串。 {"field": "some text"}
,我想将它们全部转换为数组。 {"field": ["some text"]}
我知道我可以遍历所有文件,获取字段,然后更新,但我想知道是否有更清洁的方式。
感谢。
答案 0 :(得分:10)
Nitin Garg上面的答案几乎可行,除了他的例子从字符串转换为哈希,而不是字符串转换为数组。
考虑到Joel Harris的评论,正确的解决方案如下:
db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
x.jobLocationCity = [ jobLocationCity ];
db.jobs.save(x);
});
或者如果使用db.eval:
function f() {
db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
x.jobLocationCity = [ jobLocationCity ];
db.jobs.save(x);
});
}
db.eval(f);
答案 1 :(得分:5)
实际上,find({“jobLocationCity”:{$ type:2}})将无法正常工作, 因为如果下次你将运行更新脚本,它会再次将['mystring']元素视为字符串类型。
你应该使用这样的东西来阻止它:
db.message_info.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach(
function (x) {
if (!Array.isArray(x.jobLocationCity)){
x.jobLocationCity = [ x.jobLocationCity ];
db.jobs.save(x);
}
}
)
答案 2 :(得分:3)
您可以在map / reduce的Reduce函数中执行此操作以保留mongodb中的所有处理。基本上,您可以使用map / reduce将结果放入新集合中,然后将它们复制回旧集合(或删除旧集合并重命名新集合)。这样做的好处就是可以将所有内容保存在mongo中。
更新:您可以使用其他选项db.eval。 db.eval
在服务器上执行,因此更新将在服务器上完成,没有任何流量/延迟。
我认为唯一的另一个选择是你所描述的 - 通过查询和更新每个选项在客户端上执行。
答案 3 :(得分:3)
试试这个
这是为了在mongoDB中将字段的类型从字符串更改为数组
db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).forEach( function (x) {
x.jobLocationCity = {"Location":x.jobLocationCity};
db.jobs.save(x);
});
查看$ type的链接 possible values
答案 4 :(得分:1)
从Mongo 4.2
开始,db.collection.update()
可以接受聚合管道,最终允许根据字段的当前值更新字段:
// { field: "some text" }
db.collection.update(
{},
[{ $set: { field: { ["$field"] } } }],
{ multi: true }
)
// { field: [ "some text" ] }
第一部分{}
是匹配查询,用于过滤要更新的文档(在本例中为所有文档)。
第二部分[{ $set: { field: { ["$field"] } } }]
是更新聚合管道(请注意方括号表示使用聚合管道)。 $set
($addFields
的别名)是一个新的聚合运算符,在这种情况下,它会替换字段的值(只需将其包装到数组中)。注意如何field
根据其自身的值($field
)直接进行修改。
不要忘记{ multi: true }
,否则只会更新第一个匹配的文档。
答案 5 :(得分:0)
但我想知道是否有更清洁的方式..
简短的回答是否定的。
MongoDB没有任何单一操作或命令来执行“更改类型”。
最快的方法是使用其中一个驱动程序并进行更改。您可以使用shell并编写for循环,但就原始速度而言,其他驱动程序可能更快。
如上所述,该过程中最慢的部分是将所有数据从磁盘加载到要更改的内存中,然后将该数据刷新回磁盘。即使使用神奇的“更改类型”命令也是如此。
答案 6 :(得分:0)
我认为这是正确的答案:
db.collection.update({},[{$set:{field:["$field"]}}],{ multi: true })
答案 7 :(得分:0)
已为 MongoDB 4.4 解决。
db.products.find( { "images" : { $type : 2 } } ).forEach( function (x) { x.images = [ x.images ]; db.products.save(x); });