简体   繁体   English

MongoDB 的唯一 int _id

[英]Unique int _id for MongoDB

I am trying to assign unique int for _id.我正在尝试为 _id 分配唯一的 int。 I know that ObjectID is a great option, but I need to use int as an ID in my case.我知道 ObjectID 是一个很好的选择,但在我的情况下我需要使用 int 作为 ID。 I am using Random to generate random int to assign it the new object.我正在使用 Random 生成随机 int 以将新对象分配给它。

Here is the error:这是错误:

Exception in thread "main" com.mongodb.MongoWriteException: E11000 duplicate key error 
collection: TOP100SongsUK.artists index: _id_ dup key: { _id: 484624875 }

Though, it is not true.然而,事实并非如此。 For now, my collection has a few records and that's impossible.目前,我的收藏有一些记录,这是不可能的。 What may be a trigger this issue?什么可能是触发此问题的原因?

Here is the method that writes into the DB and last method assigns an ID.这是写入数据库的方法,最后一个方法分配一个 ID。

 public boolean add(Artist artist) {
    Document artistToInsert = new Document();
    artistToInsert.append(ARTIST_ID, assignArtistID()).append(ARTIST_NAME, artist.getName());
    boolean validOperation = false;
    int attempts = 0;
    do {
        try {
            addArtist(artistToInsert);
            validOperation = true;
        } catch (DuplicateKeyException e) {
            attempts++;
            System.out.println("Incorrect ID for Artist");
        }
    } while (!validOperation || attempts < 3);
    if (attempts == 3) {
        throw new RuntimeException("Unable to add Artist - Mongo");
    }
    return true;
}

private boolean addArtist(Document artistToInsert) {
    artistCollection.insertOne(artistToInsert);
    return true;
}

private static Random intGenerator = new Random();
 private int assignArtistID() {
        return Math.abs(intGenerator.nextInt());
}

UPDATED: getNextSequence Function:更新:getNextSequence 函数:

static final String ID_PARAM = "idParam";
static final String ID_SEQ = "seq";

static int getNextSequence(MongoCollection<Document> collection){
    Document findRequest = new Document();
    findRequest.append("_id", ID_PARAM);
    Document updateRequest =  new Document();
    updateRequest.append("$inc", new Document(ID_SEQ,1));
    FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
    options.upsert(true);
    options.returnDocument(ReturnDocument.AFTER);
    Document returnDoc =  collection.findOneAndUpdate(findRequest,updateRequest,options);
    return (int) returnDoc.get(ID_SEQ);
}

It's not a good idea to use a random int to generate your _id mongo.使用随机 int 生成 _id mongo 不是一个好主意。 You should use an auto increment sequence using Mongo.您应该使用 Mongo 使用自动增量序列。

You have to create a collection for your sequence, with a sequenceName and your sequenceNumber.您必须为您的序列创建一个集合,其中包含一个 sequenceName 和您的 sequenceNumber。 Then for each insert, get your sequence, and increment it.然后对于每个插入,获取您的序列,并增加它。

Here are some links to help you with that :这里有一些链接可以帮助您解决这个问题:

The issue was with the code itself, not an auto-increment sequence.问题在于代码本身,而不是自动递增序列。 The loop was going on the second iteration, so the method to insert Object was called twice, but ID was the same in both cases.循环进行了第二次迭代,因此插入 Object 的方法被调用了两次,但 ID 在两种情况下都相同。

The first call wrote to db with correctly incremented _id, but the loop didn't break.第一次调用以正确递增的 _id 写入 db,但循环没有中断。 Thus the same object with the same id was writing to db and this caused WriteMongoException.因此,具有相同 id 的相同对象正在写入 db,这导致 WriteMongoException。

I removed a loop, works perfectly fine我删除了一个循环,工作得很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM