mongodb类型更改为数组

时间:2011-09-13 11:52:03

标签: javascript mongodb node.js

我在mongodb中有一个字符串。 {"field": "some text"},我想将它们全部转换为数组。 {"field": ["some text"]}

我知道我可以遍历所有文件,获取字段,然后更新,但我想知道是否有更清洁的方式。

感谢。

8 个答案:

答案 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);
    }
  }
)

请参阅http://docs.mongodb.org/manual/reference/operators/

答案 2 :(得分:3)

您可以在map / reduce的Reduce函数中执行此操作以保留mongodb中的所有处理。基本上,您可以使用map / reduce将结果放入新集合中,然后将它们复制回旧集合(或删除旧集合并重命名新集合)。这样做的好处就是可以将所有内容保存在mongo中。

更新:您可以使用其他选项db.evaldb.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); });