使用Java驱动程序获取mongoDB中最后插入文档的ID

113

使用Java驱动程序,有没有一种简单的方法来获取mongoDB实例中最后插入文档的ID(ObjectID)?

8个回答

202

我刚刚意识到你可以这样做:

BasicDBObject doc = new BasicDBObject( "name", "Matt" );
collection.insert( doc );
ObjectId id = (ObjectId)doc.get( "_id" );

1
它已经过时了吗? - Stu_Dent
@Stu_Dent 不是的,但如果你的 insertOne() 方法返回类型为 void,则可能是因为你正在使用已过时的 mongodb 驱动程序“mongo-java-driver”/“mongodb-driver”。现在应该使用“mongodb-driver-sync” https://mvnrepository.com/artifact/org.mongodb。 - dQw4w9WyXcQ

15
为了避免从ObjectObjectId的转换,假设有一个com.mongodb.client.MongoCollection collection和一个org.bson.Document doc,您可以执行以下操作:
collection.insert(doc);
ObjectId id = doc.getObjectId("_id");

我假设这在3.x Java驱动程序中变得可能了? - Jontia

13

这样做是安全的

doc.set("_id", new ObjectId())

如果您查看驱动程序的代码

if ( ensureID && id == null ){
    id = ObjectId.get();
    jo.put( "_id" , id );       
}

public static ObjectId get(){
    return new ObjectId();
}

你是想说“做这件事是安全的(it's safe to do)”还是“做这件事是保存的(it's save to do)”? - pd40
2
由于某些原因,在MongoDB 2.2.2(而不是之前的2.2.0版本)和Java驱动程序2.10.1中,答案中的代码无法工作。 在我将对象插入文档后,似乎无法获得其_id,即使MongoDB明确地自动生成了ObjectId。但是,您手动创建ObjectId的解决方案确实有效,感谢您提供此选项! - Apophenia Overload
以下是相关编程的内容:<code> BasicDBObject doc = new BasicDBObject("_id", new ObjectId()); System.out.println("doc.id before: " + doc.get("_id")); new Mongo("localhost").getDB("test").getCollection("t").insert(doc); System.out.println("doc.id after: " + doc.get("_id")); </code> 这段代码在新版本的mongo 2.2.2和driver 2.10.1上经过测试,可以正常运行。 - zlob

7

我不了解Java驱动程序,但为了后人,可以运行getLastError命令来获取写操作的_id,甚至是upsert(截至1.5.4版本)。


4

在将文档插入到MongoDB集合后,成功插入应更新必需字段(即_id)。您可以查询已插入的对象以获取_id。


0
在MongoTemplate.class中有一个方法。
protected <T> void doInsert(String collectionName, T objectToSave, MongoWriter<T> writer) {

    assertUpdateableIdIfNotSet(objectToSave);

    initializeVersionProperty(objectToSave);

    maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave, collectionName));

    DBObject dbDoc = toDbObject(objectToSave, writer);

    maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc, collectionName));
    Object id = insertDBObject(collectionName, dbDoc, objectToSave.getClass());

    populateIdIfNecessary(objectToSave, id);
    maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc, collectionName));
}

而且这个方法会为我们设置id

protected void populateIdIfNecessary(Object savedObject, Object id) {

    if (id == null) {
        return;
    }

    if (savedObject instanceof BasicDBObject) {
        DBObject dbObject = (DBObject) savedObject;
        dbObject.put(ID_FIELD, id);
        return;
    }

    MongoPersistentProperty idProp = getIdPropertyFor(savedObject.getClass());

    if (idProp == null) {
        return;
    }

    ConversionService conversionService = mongoConverter.getConversionService();
    MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(savedObject.getClass());
    PersistentPropertyAccessor accessor = entity.getPropertyAccessor(savedObject);

    if (accessor.getProperty(idProp) != null) {
        return;
    }

    new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, id);
}

我们可以看到,如果实体是BasicDBObject的子类,它将为我们设置一个ID。


0

我认为答案是"不可以"。

你可以手动提供_id,或者实现CollectibleCodec机制(这正是BasicBDDocument所做的)。但是所有这些解决方案都涉及在客户端生成ID。

话虽如此,我认为在客户端生成_id没有任何问题。


-2

这是插入操作:

DBCollection table1 = db.getCollection("Collection name");
BasicDBObject document = new BasicDBObject();
document.put("_id",value);      
document.put("Name", name);
table1.insert(document);

插入后,您可以获取最后插入的ID:

DBCollection tableDetails = db.getCollection("collection name");
BasicDBObject queryDetails = new BasicDBObject();
queryDetails.put("_id", value);
DBCursor cursorDetails =tableDetails.find(queryDetails);
DBObject oneDetails;
oneDetails=cursorDetails.next();        
String data=oneDetails.get("_id").toString();
System.out.println(data);

获取值后转换为整数类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接