2012-07-18 10 views
9

sto usando Mongoid (v3) per accedere MongoDB, e si vuole eseguire questa azione:Come fare un upsert/push con mongoid/motorino

db.sessionlogs.update( 
    {sessionid: '12345'}, /* selection criteria */ 
    {'$push':{rows: "new set of data"}}, /* modification */ 
    true /* upsert */ 
); 

Questo funziona bene nella shell mongo. È anche esattamente ciò che voglio dal momento che è una singola operazione atomica che è importante per me, dato che la chiamerò molto. Non voglio dover fare due operazioni: un recupero e poi un aggiornamento. Ho provato un sacco di cose attraverso mongoid, ma non riesco a farlo funzionare.

Come posso rimuovere MongoID e inviare semplicemente questo comando a MongoDB? Sto indovinando che c'è un modo per farlo a livello del ciclomotore, ma la documentazione di quella libreria è fondamentalmente inesistente.

+1

hai visto la [ciclomotori docs driver] (http://mongoid.org/en/moped/docs/ driver.html)? –

risposta

10

[risposta trovata durante la scrittura la questione ...]

criteria = Sessionlogs.collection.find(:sessionid => sessionid) 
criteria.upsert("$push" => {"rows" => datarow}) 
2

Ecco un modo per farlo:

 
session_log = SessionLog.new(session_id: '12345') 
session_log.upsert 
session_log.push(:rows, "new set of data") 

Oppure un altro:

 
SessionLog.find_or_create_by(session_id: '12345'). 
    push(:rows, "new set of data") 

#push esegue un atomico $push sul campo. È spiegato nella pagina Atomic Persistence.

(Nota: Gli esempi utilizzano UpperCamelCase e snake_case come è Rubino convenzione.)

0

Non scendere al ciclomotore appena ancora, è possibile utilizzare trovare e modificare il funzionamento per ottenere la stessa cosa (con tutto il default portata e di eredità chicche)

di esempio per salvare un vantaggio in un grafico, se non esistesse

edge = {source_id: session[:user_id],dest_id:product._id, name: edge_name} 
ProductEdge.where(edge).find_and_modify(ProductEdge.new(edge).as_document,{upsert:true}) 
Problemi correlati