You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java操作MongoDB:嵌套对象数据获取与更新异常求助

问题描述

我的MongoDB数据库中有如下文档:

_id: ObjectId('63a73aec1afb1e4de760d9de')
uuid: "71e5db4e-ab05-4de2-9238-5660474c5156"
coins: 0
level: 1
currentXp: 1
upgrades: Object
   durability: 0
   luck: 1

我用以下Java代码可以正常获取upgrades.durability的值:

public static int getDurabilityLevel(UUID uuid) {
    Document filter = new Document("uuid", uuid.toString());

    int durabilityLevel = Main.getInstance().getDataConnection().getCollection().find(filter).first().getInteger("upgrades.durability");

    return durabilityLevel;
}

但执行以下代码更新upgrades.luck时,durability字段会被删除:

public static void setLuckLevel(UUID uuid, int level) {
    Document filter = new Document("uuid", uuid.toString());

    Document foundDocument = Main.getInstance().getDataConnection().getCollection().find(filter).first();

    if(foundDocument != null) {
        Document updateValue = new Document("Upgrades", new Document("luck", level));
        Document updateOperation = new Document("$set", updateValue);

        Main.getInstance().getDataConnection().getCollection().updateOne(foundDocument, updateOperation);
    }
}
问题原因
  1. 字段大小写不匹配:文档中的嵌套字段是小写的upgrades,但更新代码中写的是大写开头的Upgrades,会导致MongoDB创建新字段。
  2. 替换整个嵌套对象:当前代码用$set直接覆盖了整个upgrades对象,新对象仅包含luck字段,原有的durability自然被删除。
解决方案

要只更新嵌套对象中的单个字段,需使用点符号指定具体嵌套路径,而非替换整个对象,同时修正字段名大小写。另外,更新操作直接用filter作为查询条件即可,无需先查询文档,避免并发问题。

修正后的代码如下:

public static void setLuckLevel(UUID uuid, int level) {
    Document filter = new Document("uuid", uuid.toString());

    // 用点符号指定嵌套字段,只更新upgrades.luck
    Document updateValue = new Document("upgrades.luck", level);
    Document updateOperation = new Document("$set", updateValue);

    Main.getInstance().getDataConnection().getCollection().updateOne(filter, updateOperation);
}
额外优化建议

获取durability时建议增加空值判断,避免空指针异常:

public static int getDurabilityLevel(UUID uuid) {
    Document filter = new Document("uuid", uuid.toString());
    Document doc = Main.getInstance().getDataConnection().getCollection().find(filter).first();
    
    if (doc != null) {
        // 第二个参数为默认值,防止字段不存在时返回null
        return doc.getInteger("upgrades.durability", 0);
    }
    // 未找到文档时返回默认值
    return 0;
}

内容的提问来源于stack exchange,提问作者Kifo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:55:21