0

我有一个 playerdata 数据库,其中包含该程序以前版本中的一些预先存在的字段。示例过时的文档:

{
   "playername": "foo"
}

但是在新版本下生成的播放器文档应该是这样的:

{
   "playername": "bar",
   "playercurrency": 20
}

问题是,如果我尝试查询我会得到一个 NullPointerException playercurrency,因为. 我想在不干扰任何其他可以存储在. 我使用示例尝试了一些代码:fooplayercurrencyfooplayercurrencyfoofoo$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因为它存在而单独存在。我可能使用存在严重错误,如果是这样,请告诉我,因为这是我的第一个 MongoDB 项目之一,我想尽可能多地学习。

4

2 回答 2

0

你必须用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 }

于 2016-04-08T06:38:21.597 回答
0

所以我知道回答你自己的问题通常不受欢迎,但没有人真正发布我最终做了什么我想借此时间感谢@Mark Watson回答并最终指导我找到我的答案。

由于检查某个字段是否null在 MongoDB Java 驱动程序中不起作用,我需要找到一种不同的方法来了解何时准备好进行更新。所以经过一些研究后,我偶然发现了这个问题,它帮助我想出了这段代码:

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 对象。

于 2016-04-08T09:22:07.497 回答