mongodb类型更改为数组

Har*_*rry 17 javascript mongodb node.js

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

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

谢谢.

小智 10

上面的Nitin Garg的答案几乎可行,除了他的例子从字符串转换为哈希,而不是字符串转换为数组.

考虑到Joel Harris的评论,正确的解决方案如下:

db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
    x.jobLocationCity = [ jobLocationCity ];
    db.jobs.save(x);
});
Run Code Online (Sandbox Code Playgroud)

或者如果使用db.eval:

function f() {
    db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).snapshot().forEach( function (x) {
        x.jobLocationCity = [ jobLocationCity ];
        db.jobs.save(x);
    });
}
db.eval(f);
Run Code Online (Sandbox Code Playgroud)

  • 小修:x.jobLocationCity = [x.jobLocationCity]; (3认同)

Xav*_*hot 6

从 开始Mongo 4.2db.collection.update()可以接受聚合管道,最后允许基于其当前值更新字段:

// { field: "some text" }
db.collection.update(
  {},
  [{ $set: { field: ["$field"] } }],
  { multi: true }
)
// { field: [ "some text" ] }
Run Code Online (Sandbox Code Playgroud)
  • 第一部分{}是匹配查询,过滤要更新的文档(在本例中为所有文档)。

  • 第二部分[{ $set: { field: { ["$field"] } } }]是更新聚合管道(注意方括号表示使用聚合管道)。$set(alias of $addFields) 是一个新的聚合运算符,在这种情况下它替换字段的值(简单地将它包装到一个数组中)。请注意如何field直接根据其自身的值 ( $field) 进行修改。

  • 不要忘记{ multi: true }(或使用updateMany),否则只会更新第一个匹配的文档。


Vit*_*mon 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);
    }
  }
)
Run Code Online (Sandbox Code Playgroud)

http://docs.mongodb.org/manual/reference/operators/


Sco*_*eke 3

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

更新:另一种选择可能是您使用db.eval来实现此目的。db.eval在服务器上执行,因此更新将在服务器上完成,没有任何流量/延迟。

我认为唯一的其他选择正如您所描述的那样 - 通过查询和更新每个选项在客户端上执行此操作。