首页 > 解决方案 > 如何在 mongo 文档中使用 java.util.Date 作为@Id

问题描述

好的,我发现自己遇到了一个简单但烦人的问题。我的 mongo 文档使用 java.util.Date 作为 id,并且您可能猜到 id 被转换(弹簧转换器)为 ObjectId,我无法更新这些文档,因为每次创建一个新的 ObjectId(Date) 时都会得到一个完整的即使日期相同,ID也不同...

我如何强制 mongo 只使用 java.util.Date 作为 id?

提供示例代码:

  public void updateNode(...node..) {
    final MongoTemplate mongoTemplate = ...
    final String collectionName = ...
    final Query query = (new Query()).addCriteria(Criteria.where("time").is(node.getTime()));
    final Update update = Update.update("time", node.getTime()).set("top", node.getTop())
          .set("bottom", node.getBottom()).set("mid", node.getMid())
          .set("startTime", node.getStartTime()).set("potential", node.isPotential());

    mongoTemplate.upsert(query, update, MyClassNode.class, collectionName);



  }

如果我第一次运行此代码将对象插入数据库但使用 ObjectId... 如果 node.getTime() 是 java.sql.Date 那么一切都很好。

如果 node.getTime() 不是 java.sql.Date 我无法更新文档(如果存在):为什么?因为每次准备文档时,它都会创建一个新的 ObjectId,更新和查询将有两个不同的 _id 字段值并且更新失败。

标签: springmongodbspring-boot

解决方案


在检查文档时,我发现了以下详细信息:

在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id 字段作为主键。如果插入的文档省略了 _id 字段,MongoDB 驱动程序会自动为 _id 字段生成一个 ObjectId。

这也适用于通过带有 upsert: true 的更新操作插入的文档。

以下是存储 _id 值的常用选项:

  • 使用 ObjectId。
  • 如果可用,请使用自然唯一标识符。这节省了空间并避免了额外的索引。
  • 生成一个自动递增的数字。

我从文档中了解到,为了避免多次插入同一个文档,仅upsert: true在查询字段被唯一索引时使用。所以,如果设置了这个标志,你会发现你的 id 使用 ObjectId() 转换以使其唯一.


推荐阅读