2012-07-18 6 views
9

Używam Mongoid (v3), aby uzyskać dostęp MongoDB i chcą wykonać tę czynność:Jak zrobić upsert/PUSH z mongoid/motorowerów

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

to działa prawidłowo w powłoce Mongo. Jest to dokładnie to, czego chcę, ponieważ jest to pojedyncza operacja atomowa, która jest dla mnie ważna, ponieważ będę ją nazywał bardzo często. Nie chcę wykonywać dwóch operacji - pobierania, a następnie aktualizacji. Próbowałem kilku rzeczy przez mongoid, ale nie mogę go uruchomić.

Jak mogę usunąć MongoID i przesłać to polecenie do MongoDB? Zgaduję, że jest jakiś sposób, aby to zrobić na poziomie Motoroli, ale dokumentacja tej biblioteki zasadniczo nie istnieje.

+1

Widziałeś [motorower docs Driver] (http://mongoid.org/en/moped/docs/ driver.html)? –

Odpowiedz

10

[Odpowiedź znaleźć pisząc pytanie ...]

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

Oto jeden ze sposobów, aby to zrobić:

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

Albo inny:

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

#push wykonuje atomowy $push na polu. Zostało to wyjaśnione na stronie Atomic Persistence.

(Uwaga: przykłady użyć UpperCamelCase i snake_case jak konwencja Ruby).

0

Nie zejść do motoroweru jeszcze, można użyć znaleźć i zmodyfikować operację, aby osiągnąć to samo (z wszystkimi Domyślnie zakres i spadkowe Korzyści)

Próbka zapisać przewagę w postaci wykresu, jeśli nie istniały

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})