2015-11-14 12 views
9

Sto cercando di ottenere l'objectId di un oggetto che ho aggiornato - questo è il mio codice Java utilizzando il driver Java:conducente Java: come ottenere l'objectId di un oggetto aggiornato con il metodo updateFirst di MongoDB

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()); 

Il messaggio di log restituisce null. Sto usando un server mongo 3.0 su mongolab perché sono sul livello gratuito quindi non dovrebbe restituire nulla. Il mio shell mongo è anche:

MongoDB versione della shell: 3.0.7

C'è un modo semplice per restituire l'ID oggetto per il documento che ho appena aggiornato? Qual è il punto del metodo getUpsertedId() se non riesco a restituire l'upsertedId?

di fare quello che voglio, ho attualmente a rilasciare due query che è altamente ingombrante:

//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()); 

Come per la risposta di David, ho anche provato il suo suggerimento utilizzare per piuttosto upsert sul modello, così ho cambiato il codice al di sotto e ancora non funziona:

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()); 

risposta

6

Simon, penso che sia possibile ottenere in una query. Quello di cui hai bisogno è un altro metodo chiamato findAndModify().

Nel driver java per mongoDB, ha un metodo chiamato findOneAndUpdate(filter, update, options).

Questo metodo restituisce il documento che è stato aggiornato. A seconda delle opzioni specificate per il metodo, questo sarà il documento come era prima dell'aggiornamento o come è dopo l'aggiornamento. Se nessun documento corrisponde al filtro query, verrà restituito null. Non è necessario passare le opzioni, in tal caso restituirà il documento che è stato aggiornato prima dell'applicazione dell'aggiornamento.

Un rapido sguardo ai mongoTemplate documentazione del driver java qui: http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/FindAndModifyOptions.html mi dice che è possibile utilizzare il metodo di chiamata:

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

si può anche cambiare la classe FindAndModifyOptions ad assumere un 'upsert' se la voce non è stato trovato nella query. Se viene trovato, l'oggetto verrà modificato.

+0

Questa sarebbe un'ottima risposta se avesse un esempio;) –

+0

@Markus Grazie, io non sono molto un java da solo. Puoi modificare la risposta se conosci il codice? –

+0

Penso che in teoria ciò funzionerebbe, ma non sono sicuro al 100% poiché non ho tempo per testarlo ultimamente. Penso che il metodo call in java sia 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 si applica solo se entrambi

  1. Le opzioni di aggiornamento sono state aggiornate su
  2. Un nuovo documento è stato effettivamente creato.

La query non ha abilitato upsert, né crea un nuovo documento. Quindi ha perfettamente senso che lo getUpsertedId() restituisca null qui.

Sfortunatamente non è possibile ottenere ciò che si desidera in una singola chiamata con l'API corrente; devi dividerlo in due chiamate. Ciò è ulteriormente indicato dall'API shell di Mongo per WriteResults:

_id del documento inserito da un upsert. Restituito solo se un risultato di risulta in un inserto.

+0

Ciao David, anche se ho usato il metodo: WriteResult writeResult = mongoTemplate.upsert (query, di aggiornamento, Colors.class); e prova ad ottenere l'id con getUpsertedId() su di esso, non restituisce ancora l'id. – Simon

+0

@Simon Sembra che tu stia correndo su un documento già esistente, quindi è logico. Vedere il punto 2. Prova a creare la query 'query.addCriteria (Criteria.where (" color "). Is (" adasdasdsadsa "));' –

+0

Ma al punto 1 hai detto che le opzioni di aggiornamento sono aumentate. Nel mio caso, il mongoTemplate è salito su così dovrebbe funzionare ... Anche il codice che hai suggerito sopra non avrebbe senso visto che poi dovrei creare un nuovo documento. Non sto creando un nuovo documento, ma semplicemente modificando il mio documento esistente con uno scostamento altrimenti, potrei facilmente fare un salvataggio e ottenere l'id attraverso il metodo mongoTemplate.save. – Simon

0

Questo è un esempio di fare questo con findOneAndUpdate (filtro, aggiornamento, opzioni) in Scala:

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) 
Problemi correlati