2013-10-15 17 views
10

Mam kolekcję z wielu podobnych dokumentów zorganizowanego, dwa dokumentu wyglądaAgregacja z aktualizacji MongoDB

Wejście:

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

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

Domyślnie clear dla wszystkich dokumentów jest "No",

Req: Muszę dodać wynik wszystkich dokumentów z tym samym cust_id, pod warunkiem, że należą one do status"A" i "B". Jeśli score przekracza 2000, to muszę zaktualizować atrybut clear do "Yes" dla całego dokumentu z tym samym cust_id.

oczekiwany wynik:

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

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

Tak, bo 1600 + 500 = 2100 i 2100> 2000.


moje podejście: Udało mi tylko, aby uzyskać sumę przez funkcję zagregowanego ale nie udało się zaktualizować:

Proszę zasugerować, jak mogę kontynuować.

góry dzięki :)

+0

Mógłbyś opisać jak doszło do awarii? Czy był jakiś błąd, czy coś w tym stylu? –

+0

Brak błędów per se, ale trudno mi było mieć aktualizację i agregację funkcji razem w oświadczeniu, jestem bardzo nowy w mongodb, próbuję scenariusza w cmd. – Sam

Odpowiedz

10

Po wielu kłopotów, eksperymentowanie Mongo skorupę Mam wreszcie rozwiązanie moje pytanie.

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

Proszę o komentarz, jeśli masz jakieś inne rozwiązanie dla tego samego pytania.

5

Trzeba to zrobić w dwóch etapach:

  1. zidentyfikować klientów (cust_id) z sumą większą niż 200
  2. Dla każdego z tych klientów, zestaw clear do Yes

Już masz dobre rozwiązanie dla pierwszej części. Druga część powinna być implementowana jako oddzielne wywołania update() do bazy danych.

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

To nie jest idealny, ponieważ trzeba nawiązać połączenie z bazą danych dla każdego klienta. Jeśli chcesz często wykonywać tego rodzaju operacje, możesz zmienić swój schemat tak, aby zawierał całkowity wynik w każdym dokumencie. (To musiał być utrzymywany przez aplikację). W tym przypadku, można wykonać aktualizację za pomocą jednego polecenia:

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

Cześć, dziękuję za rozwiązanie, próbowałem uruchomić powyższy kod, dając mi błąd. 1. błąd składniowy: nieoczekiwany identyfikator, 2. nie może być niezdefiniowany w wyrażeniu zapytania. czy mógłbyś napisać pełny kod w formacie, ponieważ jestem nowy w mongoDB. – Sam

+0

Użyłem psudokodu, ponieważ musi on zostać zaimplementowany na poziomie aplikacji i nie określa się, z którym sterownikiem pracujesz. Mógłbym zrobić wersję Python (pymongo) lub wymyślić sposób, by zrobić to bezpośrednio ze skryptem dla powłoki Mongo. Które z nich byłyby bardziej pomocne? – SuperAce99

+0

Próbuję uruchomić kod za pomocą cmd. Domyślam się, że skrypt dla powłoki mongo może pomóc. Próbuję zbadać możliwości mongo, wypróbowując różne scenariusze. Czy mógłbyś też zaproponować mi dobry interfejs do pracy na mongo, ponieważ cmd jest dość frustrujący. – Sam

Powiązane problemy