gpt4 book ai didi

java - 使用 DBCollection.mapReduce 更改 MongoDB 架构 : spurious nested "value" attribute

转载 作者:行者123 更新时间:2023-12-02 02:11:35 24 4
gpt4 key购买 nike

我需要创建一个数据库补丁,将 MongoDB 集合的所有元素更新为新格式。例如,经过大大简化,旧格式的文档如下:

{
"_id" : ObjectId("572a7f30200cd11355083cd9"),
"_class" : "Domain",
"oldAttribute": 123
}

新格式需要这样的文档:

{
"_id" : ObjectId("572a7f30200cd11355083cd9"),
"_class" : "Domain",
"newAttribute": 123
}

我正在使用 MongoDB 的 Java API,数据库补丁也必须用 Java 编写,但我认为我不是编写一堆通过首先读取文档然后写回文档来修改文档的 Java 代码可以利用 DBCollection.mapReduce() 和 MapReduceCommand.OutputType.REPLACE 直接在 MongoDB 中使用一小段 JavaScript 执行相同的操作,如下所示:

myCollection.mapReduce(map, reduce, "myCollection", MapReduceCommand.OutputType.REPLACE, null);

对于 map 函数,我传递了如下内容:

function () {
var copy = {'_id': this._id, '_class': this._class, newAttribute: this.oldAttribute};
emit(this._id, copy);
}

从技术上讲,reduce 函数不应该被调用,因为键是唯一的,所以我只是在那里传递一个虚拟函数。

这似乎可行,但有一个问题:应用map-reduce后,集合中的所有文档现在都有一个嵌套的value属性:

{
"_id": { "$oid" : "56c2371a200cd11088252111"},
"value":
{
"_id": { "$oid" : "56c2371a200cd11088252111"},
"_class": "Domain",
"newAttribute": 123.0
}
}

(此输出是从 Java 控制台粘贴的,因此格式略有不同)

简而言之,我的问题是:如何摆脱嵌套的 value 属性并将所有属性(包括 _id)置于顶层?

最佳答案

如果你想就地修改文档,可以使用 $rename 进行更新修饰符。使用 multi:true 运行更新将更新集合中的每个文档。

如果您希望更改显示为“原子”并且集合不分片,则可以将 aggregate$out 一起使用。和这个管道:

db.collection.aggregate([ 
{$project:{_class:1, newAttribute:"$oldAttribute"}},
{$out:"collection"}
])

$out 提供与原始集合名称相同的名称将会将该集合替换为其新转换的版本。

如果您想创建集合的新版本而不删除旧版本,则只需为 $out 指定一个新的集合名称即可。

关于java - 使用 DBCollection.mapReduce 更改 MongoDB 架构 : spurious nested "value" attribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49928639/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com