2013-10-15 16 views
10

Ho una collezione con molti documenti strutturati simili, due del documento appare comeaggregazione con l'aggiornamento in MongoDB

ingresso:

{ 
    "_id": ObjectId("525c22348771ebd7b179add8"), 
    "cust_id": "A1234", 
    "score": 500, 
    "status": "A" 
    "clear": "No" 
} 

{ 
    "_id": ObjectId("525c22348771ebd7b179add9"), 
    "cust_id": "A1234", 
    "score": 1600, 
    "status": "B" 
    "clear": "No" 
} 

Di default il clear per tutti i documenti è "No",

Req: Devo aggiungere il punteggio di tutti i documenti con lo stesso cust_id, a condizione che appartengano a status"A" e status"B". Se lo score supera 2000, allora devo aggiornare l'attributo clear a "Yes" per tutto il documento con lo stesso cust_id.

uscita prevista:

{ 
    "_id": ObjectId("525c22348771ebd7b179add8"), 
    "cust_id": "A1234", 
    "score": 500, 
    "status": "A" 
    "clear": "Yes" 
} 

{ 
    "_id": ObjectId("525c22348771ebd7b179add9"), 
    "cust_id": "A1234", 
    "score": 1600, 
    "status": "B" 
    "clear": "Yes" 
} 

Sì, perché 1600 + 500 = 2100, e il 2100> 2000.


mio approccio: sono stato in grado di ottenere la somma per funzione di aggregazione solo, ma fallito ad aggiornare

db.aggregation.aggregate([ 
    {$match: { 
     $or: [ 
      {status: 'A'}, 
      {status: 'B'} 
     ] 
    }}, 
    {$group: { 
     _id: '$cust_id', 
     total: {$sum: '$score'} 
    }}, 
    {$match: { 
     total: {$gt: 2000} 
    }} 
]) 

prega di suggerire me come procedo.

Grazie in anticipo :)

+0

Potresti descrivere come si è verificato il fallimento? C'è stato un errore o qualcosa del genere? –

+0

Nessun errore di per sé, ma ho trovato difficoltà ad avere funzioni di aggiornamento e aggregazione insieme in una dichiarazione, sono molto nuovo a mongodb, sto provando lo scenario in cmd. – Sam

risposta

10

Dopo un sacco di problemi, sperimentando mongo shell ho finalmente una soluzione per la mia domanda.

Psudocode:

# To get the list of customer whose score is greater than 2000 
cust_to_clear=db.col.aggregate(
    {$match:{$or:[{status:'A'},{status:'B'}]}}, 
    {$group:{_id:'$cust_id',total:{$sum:'$score'}}}, 
    {$match:{total:{$gt:500}}}) 

# To loop through the result fetched from above code and update the clear 
cust_to_clear.result.forEach 
(
    function(x) 
    { 
    db.col.update({cust_id:x._id},{$set:{clear:'Yes'}},{multi:true}); 
    } 
) 

Si prega di commentare, se si dispone di una soluzione diversa per la stessa domanda.

5

Hai bisogno di fare questo in due fasi:

  1. identificare i clienti (cust_id) con un punteggio totale superiore a 200
  2. Per ognuno di questi clienti, set clear al Yes

Hai già una buona soluzione per la prima parte. La seconda parte dovrebbe essere implementata come chiamate update() separate al database.

Psudocode:

# Get list of customers using the aggregation framework 
cust_to_clear = db.col.aggregate(
    {$match:{$or:[{status:'A'},{status:'B'}]}}, 
    {$group:{_id:'$cust_id', total:{$sum:'$score'}}}, 
    {$match:{total:{$gt:2000}}} 
    ) 

# Loop over customers and update "clear" to "yes" 
for customer in cust_to_clear: 
    id = customer[_id] 
    db.col.update(
     {"_id": id}, 
     {"$set": {"clear": "Yes"}} 
    ) 

Questo non è l'ideale perché si deve effettuare una chiamata al database per ogni cliente. Se è necessario eseguire spesso questo tipo di operazione, è possibile modificare lo schema per includere il punteggio totale in ciascun documento. (Questo dovrebbe essere mantenuto da l'applicazione.) In questo caso, si potrebbe fare l'aggiornamento con un solo comando:

db.col.update(
    {"total_score": {"$gt": 2000}}, 
    {"$set": {"clear": "Yes"}}, 
    {"multi": true} 
    ) 
+0

Ciao, grazie per la soluzione, ho cercato di eseguire il codice sopra riportato, dandomi qualche errore. 1. Errore di sintassi: identificatore inatteso, 2. non può essere definito in un'espressione di query. potresti scrivere il codice completo in formato, perché sono davvero nuovo in mongoDB. – Sam

+0

Ho usato psudocode perché deve essere implementato a livello di applicazione e non si specifica il driver con cui si sta lavorando. Potrei fare una versione di Python (pymongo) o forse trovare un modo per farlo direttamente con lo script per la shell di Mongo. Quale di questi sarebbe più utile? – SuperAce99

+0

Sto provando ad eseguire il codice tramite cmd immagino che lo script per la shell mongo possa essere d'aiuto. Sto cercando di esplorare le capacità di mongo provando diversi scenari. Potresti anche suggerirmi una buona interfaccia utente per lavorare su mongo perché cmd è piuttosto frustrante. – Sam

Problemi correlati