【问题标题】:MongoDB Java Driver Update Sub-DocumentMongoDB Java 驱动更新子文档
【发布时间】:2015-11-20 18:34:21
【问题描述】:

我正在尝试通过 MongoDB Java 驱动程序更新子文档。

我在 Mongo 中有以下结构:

    {
        "_id" : "9999996978c9df5b02999999",
        "title" : "The Effects of Glaze on Pottery",
        "numberOfDownloads" : "453",
        "summary" : "This is a summary of the document",
        "documents" : {
                "file" : "99991F64C16E9A0954E89999",
                "mimetype" : "document/pdf",
                "pages" : "415",
                "downloads" : "453"
        }
}

使用 Java 驱动程序,我可以通过这种方式很好地更新根文档的“numberOfDownloads”字段:

        Document updDocQuery = new Document("_id", "9999996978c9df5b02999999");

        Document updDocValues = new Document("numberOfDownloads","555");

        Document updDocSet = new Document("$set",updDocValues);

        System.out.println(updDocSet.toJson());

        collection.updateOne(updDocQuery, updDocSet);

效果很好。

现在我也在尝试更新子文档“文档”以将“下载”值也设置为相同 - 我正在尝试这样的事情:

        Document updDocQuery = new Document("_id", "9999996978c9df5b02999999");

        Document updDocValues = new Document("numberOfDownloads","555");

        Document updSubDocValues = new Document("downloads","555");

        updDocValues.append("documents", updSubDocValues);
        Document updDocSet = new Document("$set",updDocValues);

        System.out.println(updDocSet.toJson());

        collection.updateOne(updDocQuery, updDocSet);

这会适当地将“文档”属性更新为我的新值 - 但我想更新特定字段并保持其他字段不变。

我最终在 Mongo 中得到了一个结果文档:

    {
        "_id" : "9999996978c9df5b02999999",
        "title" : "The Effects of Glaze on Pottery",
        "numberOfDownloads" : "555",
        "summary" : "This is a summary of the document",
        "documents" : {
                "downloads" : "555"
        }
}

我需要它是:

    {
        "_id" : "9999996978c9df5b02999999",
        "title" : "The Effects of Glaze on Pottery",
        "numberOfDownloads" : "555",
        "summary" : "This is a summary of the document",
        "documents" : {
                "file" : "99991F64C16E9A0954E89999",
                "mimetype" : "document/pdf",
                "pages" : "415",
                "downloads" : "555"
        }
}

我宁愿不必提取记录、将其转换为对象、更新值并提交它以进行更新——但这似乎效率低下。

我可以从 Mongo 控制台执行这个查询,效果很好:

db.Paper.update(
    {"_id" : "5617776978c9df5b02f68228"},
    {$set: 
        { "numberOfDownloads" : "453", 
          "documents" : 
                { "downloads" : "453"}
        }
    });

我只是错过了一些简单的东西 - 还是 - 我把它复杂化了?

【问题讨论】:

  • 错误是什么?它覆盖了documents 对象?
  • 正确。与以具有更新值的子对象结束相反,整个子文档被覆盖,因此它只有下载属性。我更新了原始帖子,提供了有关当前输出和所需输出的更多信息。

标签: java mongodb


【解决方案1】:

如果这是 mongodb 中设置的更新:

 {$set: 
        { "numberOfDownloads" : "453", 
          "documents" : 
                { "downloads" : "453"}
        }
 }

您可以这样使用 Document 类:

Document upDocValue = new Document("numberOfDownloads": "453")
                      .append("documents.downloads":"453");

这会给你:

{
  "numberOfDownloads": "453",
  "documents" : 
    { "downloads" : "453"}
}

然后您可以使用以下命令创建外部文档:

Document upDocSet = new Document("$set",updDocValue);

这应该给你:

{$set: 
      { "numberOfDownloads" : "453", 
            "documents" : 
                  { "downloads" : "453"}
      }
}

然后你在这里运行你的查询:

collection.updateOne(upDocQuery,upDocSet);

所以你最终有:

Document updDocQuery = new Document("_id", "9999996978c9df5b02999999");

Document upDocValue = new Document("numberOfDownloads": "453")
                          .append("documents.downloads":"453");

Document upDocSet = new Document("$set",updDocValue);

collection.updateOne(upDocQuery,upDocSet);

【讨论】:

  • 我在文档中看到了这一点 - 我试图在单个 updateOne() 中进行两个更新,而不是多个更新。任何想法是否可能 - 即:更新根“numberOfDownloads”属性和子文档的“downloads”属性。如果我必须分两步完成,我可以接受,只是真的在寻找类似于我可以在 Mongo 中本地执行的查询的单步更新。再次感谢!
  • 像魅力一样工作 - 我现在看到了嵌入文档的不同之处,而您的版本只是附加了第二个标准。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多