更改文档结构后更新 mongoDB java 驱动程序中已有的文档
Updating pre-existing documents in mongoDB java driver when you've changed document structure
我有一个播放器数据数据库,其中包含该程序以前版本中的一些预先存在的字段。过时文档示例:
{
"playername": "foo"
}
但是在新版本下生成的播放器文档是这样的:
{
"playername": "bar",
"playercurrency": 20
}
问题是,如果我尝试在 foo
上查询 playercurrency
,我会得到 NullPointerException,因为 playercurrency
对于 foo
不存在。我想将 playercurrency
字段添加到 foo
,而不影响可以存储在 foo
中的任何其他数据。我已经使用 $exists
示例尝试了一些代码:
players.updateOne(new Document("playername", "foo"), new Document("$exists", new Document("playername", "")));
players.updateOne(new Document("playername", "foo"), new Document("$exists", new Document("playercurrency", 20)));
我的想法是它只更新 playercurrency
因为它不存在并且它会单独留下 playername
因为它存在。我可能使用的 exists 非常错误,如果是这样请告诉我,因为这是我的第一个 MongoDB 项目,我想尽可能多地学习。
您必须使用 java 执行此操作吗?每当我添加一个我想要的新字段时,我只需使用命令行来迁移所有现有文档。这将遍历所有没有玩家货币的玩家并将其设置为 0(更改为您想要的任何默认值):
db.players.find({playercurrency:null}).forEach(function(player) {
player.playercurrency = 0; // or whatever default value
db.players.save(player);
});
这将导致您拥有以下文件:
{
"playername" : "foo",
"playercurrency" : 0
}
{
"playername" : "bar",
"playercurrency" : 20
}
所以我知道通常不赞成回答您自己的问题,但没有人真正发布我最终所做的事情我想借此机会感谢 @Mark Watson 的回答并最终指导我找到我的答案。
由于检查某个字段是否 null
在 MongoDB Java 驱动程序中不起作用,我需要找到一种不同的方法来了解什么时候准备更新.因此,经过一些研究后,我偶然发现了 this question,它帮助我想出了这段代码:
private static void updateValue(final String name, final Object defaultValue, final UUID key) {
if (!exists(name, key)) {
FindIterable iterable = players.find(new Document("_id", key));
iterable.forEach(new Block<Document>() {
@Override
public void apply(Document document) {
players.updateOne(new Document("_id", key), new Document("$set", new Document(name, defaultValue)));
}
});
}
}
private static boolean exists(String name, UUID key) {
Document query = new Document(name, new Document("$exists", true)).append("_id", key);
return players.count(query) == 1;
}
显然,这对我想做的事情有点专门化,但只要稍加修改,就可以轻松更改它以处理您可能需要的任何内容。确保将 players
替换为您的 Collection 对象。
我有一个播放器数据数据库,其中包含该程序以前版本中的一些预先存在的字段。过时文档示例:
{
"playername": "foo"
}
但是在新版本下生成的播放器文档是这样的:
{
"playername": "bar",
"playercurrency": 20
}
问题是,如果我尝试在 foo
上查询 playercurrency
,我会得到 NullPointerException,因为 playercurrency
对于 foo
不存在。我想将 playercurrency
字段添加到 foo
,而不影响可以存储在 foo
中的任何其他数据。我已经使用 $exists
示例尝试了一些代码:
players.updateOne(new Document("playername", "foo"), new Document("$exists", new Document("playername", "")));
players.updateOne(new Document("playername", "foo"), new Document("$exists", new Document("playercurrency", 20)));
我的想法是它只更新 playercurrency
因为它不存在并且它会单独留下 playername
因为它存在。我可能使用的 exists 非常错误,如果是这样请告诉我,因为这是我的第一个 MongoDB 项目,我想尽可能多地学习。
您必须使用 java 执行此操作吗?每当我添加一个我想要的新字段时,我只需使用命令行来迁移所有现有文档。这将遍历所有没有玩家货币的玩家并将其设置为 0(更改为您想要的任何默认值):
db.players.find({playercurrency:null}).forEach(function(player) {
player.playercurrency = 0; // or whatever default value
db.players.save(player);
});
这将导致您拥有以下文件:
{
"playername" : "foo",
"playercurrency" : 0
}
{
"playername" : "bar",
"playercurrency" : 20
}
所以我知道通常不赞成回答您自己的问题,但没有人真正发布我最终所做的事情我想借此机会感谢 @Mark Watson 的回答并最终指导我找到我的答案。
由于检查某个字段是否 null
在 MongoDB Java 驱动程序中不起作用,我需要找到一种不同的方法来了解什么时候准备更新.因此,经过一些研究后,我偶然发现了 this question,它帮助我想出了这段代码:
private static void updateValue(final String name, final Object defaultValue, final UUID key) {
if (!exists(name, key)) {
FindIterable iterable = players.find(new Document("_id", key));
iterable.forEach(new Block<Document>() {
@Override
public void apply(Document document) {
players.updateOne(new Document("_id", key), new Document("$set", new Document(name, defaultValue)));
}
});
}
}
private static boolean exists(String name, UUID key) {
Document query = new Document(name, new Document("$exists", true)).append("_id", key);
return players.count(query) == 1;
}
显然,这对我想做的事情有点专门化,但只要稍加修改,就可以轻松更改它以处理您可能需要的任何内容。确保将 players
替换为您的 Collection 对象。