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

如何在Java操作MongoDB时忽略重复的System.UniqueNumber字段值

解决方案

要实现插入时忽略System.UniqueNumber重复的文档,必须从数据库层面约束唯一性+代码层面处理重复插入异常两个步骤入手,具体如下:

1. 创建唯一索引

首先在MongoDB中为System.UniqueNumber字段创建唯一索引,确保数据库层面阻止重复数据写入,这是避免并发场景下重复插入的核心保障。

方式一:MongoDB Shell执行

db.Database.createIndex({"System.UniqueNumber": 1}, {unique: true, background: true})

方式二:Java代码初始化时创建

可以在项目启动或集合初始化时执行一次:

MongoDatabase database = mongoClient.getDatabase("Database");
MongoCollection<Document> collection = database.getCollection("Database");
// 创建唯一索引,background设为true避免阻塞其他操作
collection.createIndex(Indexes.ascending("System.UniqueNumber"), new IndexOptions().unique(true).background(true));

2. 修改Java插入代码

原代码直接用insertMany会在遇到重复数据时抛出异常并终止所有插入,我们改用bulkWrite实现跳过重复文档、继续插入其余有效数据的逻辑:

public boolean create(@Valid @RequestBody Document... documents) {
    MongoDatabase database = this.mongoClient.getDatabase("Database");
    MongoCollection<Document> collection = database.getCollection("Database");

    List<InsertOneModel<Document>> insertModels = new ArrayList<>(documents.length);
    for (Document doc : documents) {
        // 修正原代码笔误:将booking改为doc
        Document document = Document.parse(doc.toJson());
        insertModels.add(new InsertOneModel<>(document));
    }

    try {
        // ordered(false)表示遇到错误不中断,继续处理后续文档
        BulkWriteResult result = collection.bulkWrite(insertModels, new BulkWriteOptions().ordered(false));
        // 可根据业务需求返回结果,比如只要有成功插入就返回true
        return result.getInsertedCount() > 0;
    } catch (MongoBulkWriteException e) {
        // 过滤重复键错误(错误码11000),其他异常正常抛出
        boolean hasNonDuplicateError = e.getWriteErrors().stream()
                .anyMatch(error -> error.getCode() != 11000);
        if (hasNonDuplicateError) {
            throw e;
        }
        // 仅存在重复键错误时,返回true(表示有效文档已处理)
        return true;
    }
}

关键说明

  • 唯一索引错误码为11000,捕获MongoBulkWriteException后可通过错误码判断是否为重复数据,跳过此类错误即可。
  • ordered(false)确保遇到重复文档时,不会中断后续文档的插入操作。
  • 原代码中存在笔误:bookings.length应改为documents.length,booking.toJson()应改为doc.toJson(),需修正。

为什么之前的upsert不适用?

upsert的逻辑是存在则更新,不存在则插入,而你的需求是存在则忽略,不存在则插入,两者逻辑不符,因此upsert无法满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:45:39