2012-04-05 6 views
0

ich mit einer Liste der BenachrichtigungenMongoDB Position Operator nur erste Abhilfe abgestimmt

{ 
"notifications": { 
"0": { 
    "id": "1", 
    "isRead": false, 
    "user": { 
    "id": ObjectId("4f7999c5e4b0f2e6b8490e08"), 
    "firstName": "X", 
    "lastName": "Y", 
    "profilePictureUrl": "URL1" 
    } 
}, 
"1": { 
    "id": "2", 
    "user": { 
    "id": ObjectId("4f7999c5e4b0f2e6b8490e08"), 
    "firstName": "X", 
    "lastName": "Y", 
    "profilePictureUrl": "URL1" 
    } 
    } 
    }, 
} 

ein Benutzerobjekt haben Wenn ein Benutzer ändert sein Profilbild ich alle entsprechenden Meldungen aktualisieren möchten. Ich versuche so etwas in Morphia zu machen, aber es scheint nur den ersten Eintrag zu aktualisieren.

Query<UserEntity> query = ds.createQuery(UserEntity.class).filter("notifications.user.id", 
       userProperties.id).field("notifications.user.profilePictureUrl").notEqual(userProperties.profilePictureUrl); 
     UpdateOperations<UserEntity> op = ds.createUpdateOperations(UserEntity.class).disableValidation() 
       .set("notifications.$.user.profilePictureUrl", userProperties.profilePictureUrl); 
     results = update(query, op); 

Gibt es eine Umgehungsmöglichkeit dafür? Ich mache das in einem Hintergrundjob, also wird eine kostspieligere Lösung auch funktionieren.

Antwort

3

Das Problem liegt in der Verwendung von $ Operator. Derzeit gilt der Operator $ nur für das erste übereinstimmende Element in der Abfrage. http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

Sie sollten eine ganze Liste aktualisieren (holen, ändern und speichern).

+0

Yuck, das scheint der Fall zu sein. Morphia gibt [UpdateResults] zurück (http://code.google.com/p/morphia/source/browse/trunk/morphia/src/main/java/com/google/code/morphia/query/UpdateResults.java?r=) 1796), die eine Methode getUpdatedCount() hat. Selbst wenn ich diese Abfrage in einer Schleife abspiele, bis getUpdatedCount 0 ist, scheint es nicht - es scheint, als würde mongodb die vorherige Operation zwischenspeichern! –

+0

Die andere Möglichkeit besteht darin, Ihr Datenmodell zu überprüfen. Sie können eine Zuordnung anstelle der Liste verwenden: user id -> {first_name: ..., last_name ...} –

0

Ich denke, Sie können den Positionsoperator mit $ elemMatch-Operator kombinieren, um mehrere Felder und mehrere Dokumente im Unterfeld zu vergleichen.

Check this example aus einem MongoDB-Fehlerbericht mit einem ähnlichen Fall.