如何将MongoDB字段更改为单个元素数组?

jgzswidk  于 2023-06-29  发布在  Go
关注(0)|答案(8)|浏览(152)

我在mongodb中有一个字符串字段:{"field": "some text"}。我想把它们都转换成包含字符串的单元素数组:{"field": ["some text"]}
我知道我可以遍历所有文档,获取字段,然后更新,但我想知道是否有更干净的方法。

vof42yt1

vof42yt11#

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

// { field: "some text" }
db.collection.updateMany(
  {},
  [{ $set: { field: ["$field"] } }]
)
// { field: [ "some text" ] }
  • 第一部分{}是匹配查询,过滤要更新的文档(在本例中是所有文档)。
  • 第二部分[{ $set: { field: { ["$field"] } } }]是更新聚合管道(注意方括号表示使用聚合管道)。$set$addFields的别名)是一个新的聚合运算符,在本例中,它替换了字段的值(简单地将其 Package 到数组中)。注意field是如何根据它自己的值($field)直接修改的。
aamkag61

aamkag612#

上面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);
e0bqpujr

e0bqpujr3#

实际上,find({“jobLocationCity”:{ $type:2 } })将无法正常工作,因为如果您下次运行update脚本,它将再次将['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/

72qzrwbm

72qzrwbm4#

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

更新:另一个选择是使用db.eval。db.eval在服务器上执行,因此更新将在服务器上完成,没有任何流量/延迟。

我认为唯一的其他选择是如您所描述的-在客户端上通过查询和更新每个选项来完成。

hpcdzsge

hpcdzsge5#

试试这个
这是为了在mongoDB中将字段的类型从字符串更改为数组

db.jobs.find( { "jobLocationCity" : { $type : 2 } } ).forEach( function (x) {
    x.jobLocationCity = {"Location":x.jobLocationCity};
    db.jobs.save(x);
});

查看$type的可能值的链接

szqfcxe2

szqfcxe26#

但我想知道有没有更干净的方法
简短的回答是否定的。
MongoDB没有任何单一的操作或命令来执行“更改类型”。
最快的方法可能是使用其中一个驱动程序并进行更改。您可以使用shell并编写for循环,但就原始速度而言,其他驱动程序可能更快。
也就是说,这个过程中最慢的部分是将所有数据从磁盘加载到内存中进行更改,然后将这些数据刷新回磁盘。即使使用一个神奇的“更改类型”命令也是如此。

x0fgdtte

x0fgdtte7#

我认为这是正确的答案:

db.collection.update({},[{$set:{field:["$field"]}}],{ multi: true })
nwwlzxa7

nwwlzxa78#

解决了MongoDB 4.4。

db.products.find( { "images" : { $type : 2 } } ).forEach( function (x) { x.images = [ x.images ]; db.products.save(x); });

相关问题