2015-11-14 59 views
9

我試圖讓我已經更新對象的OBJECTID一個更新的對象的OBJECTID - 這是一個使用Java驅動程序我的Java代碼:Java驅動程序:如何獲得與MongoDB的updateFirst方法

Query query = new Query(); 
    query.addCriteria(Criteria.where("color").is("pink")); 
    Update update = new Update(); 
    update.set("name", name); 
    WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class); 

    Log.e("object id", writeResult.getUpsertedId().toString()); 

日誌消息返回null。我在mongolab上使用mongo服務器3.0,因爲我在免費層上,所以它不應該返回null。我蒙戈外殼也:

MongoDB的外殼版本:3.0.7

有沒有一種簡單的方法返回對象ID爲我剛剛更新了文檔?如果我無法返回upsertedId,getUpsertedId()方法的要點是什麼?

做我想做什麼,我現在必須發出兩個疑問這是非常麻煩的:

//1st query - updating the object first 
    Query query = new Query(); 
    query.addCriteria(Criteria.where("color").is("pink")); 
    Update update = new Update(); 
    update.set("name", name); 
    WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class); 
    //2nd query - find the object so that I can get its objectid 
    Query queryColor = new Query(); 
    queryColor.addCriteria(Criteria.where("color").is("pink")); 
    queryColor.addCriteria(Criteria.where("name").is(name)); 
    Color color = mongoTemplate.findOne(queryColor, Color.class); 
    Log.e("ColorId", color.getId()); 

按照大衛的回答,我甚至試過他的建議對模板而使用UPSERT,所以我改變代碼下面,它仍然不工作:

Query query = new Query(); 
    query.addCriteria(Criteria.where("color").is("pink")); 
    Update update = new Update(); 
    update.set("name", name); 
    WriteResult writeResult = mongoTemplate.upsert(query, update, Colors.class); 

    Log.e("object id", writeResult.getUpsertedId().toString()); 

回答

6

西蒙,我認爲它可能在一個查詢中實現。您需要的是另一種稱爲findAndModify()的方法。

在mongoDB的java驅動程序中,它有一個名爲findOneAndUpdate(filter, update, options)的方法。

此方法返回已更新的文檔。根據您爲該方法指定的選項,這將是更新前的文檔或更新後的文檔。如果沒有文檔匹配查詢過濾器,則返回null。它不需要傳遞選項,在這種情況下,它將返回應用更新操作之前更新的文檔。

就讓我們來看看在mongoTemplate Java驅動程序文件的位置:http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/FindAndModifyOptions.html告訴我,你可以使用方法調用:如果該項目

public <T> T findAndModify(Query query, 
          Update update, 
          FindAndModifyOptions options, 
          Class<T> entityClass) 

您也可以改變一個「UPSERT」的FindAndModifyOptions類取在查詢中找不到。如果找到,該對象將被修改。

+0

這將是一個很好的答案,如果它有一個例子;) –

+0

@Markus謝謝你,我自己並不是一個java人。如果你知道代碼,你可以編輯答案嗎? –

+0

我認爲理論上這可行,但我不是100%確定的,因爲我最近沒有時間去測試它。我認爲java中的方法調用是findAndModify:http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoTemplate.html#findAndModify-org .springframework.data.mongodb.core.query.Query-org.springframework.data.mongodb.core.query.Update-org.springframework.data.mongodb.core.FindAndModifyOptions-java.lang.Class- – Simon

1

的Upsert只適用於當兩個

  1. 更新選項有
  2. upsert實際上創建了一個新文檔。

您的查詢既沒有啓用upsert,也沒有創建新文檔。因此,getUpsertedId()在這裏返回null非常有意義。

不幸的是,在當前API的單次調用中無法獲得您想要的內容;你需要將它分成兩個呼叫。這進一步表示爲WriteResults的Mongo shell API:

由upsert插入的文檔的_id。 僅當 插入導致插入時才返回。

+0

您好大衛,即使我所用的方法:寫結果寫結果= mongoTemplate.upsert(查詢,更新Colors.class);並嘗試獲取帶有getUpsertedId()的id,它仍然不會返回id。 – Simon

+0

@Simon這聽起來像是你在一個已經存在的文檔上運行upsert,所以這是有道理的。見第2點。嘗試進行查詢query.addCriteria(Criteria.where(「color」)。is(「adasdasdsadsa」));' –

+0

但是在第1點中,您說更新選項已被插入。在我的情況下,mongoTemplate已經插入,所以它應該工作...另外,你上面建議的代碼是沒有意義的,因爲那樣我就不得不創建一個新的文檔。我沒有創建一個新文檔,只是通過一個upsert修改了我現有的文檔,否則我可以輕鬆地保存並通過mongoTemplate.save方法獲取id。 – Simon

0

這是Scala與findOneAndUpdate(過濾器,更新選項)來做到這一點的一個示例:

val findOneAndUpdateOptions = new FindOneAndUpdateOptions 
findOneAndUpdateOptions.returnDocument(ReturnDocument.AFTER) 
val filter = Document.parse("{\"idContrato\":\"12345\"}") 
val update = Document.parse("{ $set: {\"descripcion\": \"New Description\" } }") 
val response = collection.findOneAndUpdate(filter,update,findOneAndUpdateOptions) 
println(response) 
相關問題