2010-12-17 18 views
13

Mam następujący obiekt MongoDB:PHP/MongoDB: aktualizuje wartość w tablicy

{ 
    "_id": ObjectId("4d0b9c7a8b012fe287547157"), 
    "messages": { 
    "0": { 
     "toUname": "Eamorr3", 
     "fromUname": "Eamorr2", 
     "time": 1292606586, 
     "id": "ABCDZZZ", 
     "subject": "asdf", 
     "message": "asdf", 
     "read": 0 //I want to change this to 1! 
    }, 
    "1": { 
     "toUname": "Eamorr1", 
     "fromUname": "Eamorr3", 
     "time": 1292606586, 
     "id": "EFGHZZZ", 
     "subject": "asdf2", 
     "message": "asdf2", 
     "read": 0 
    } 
    }, 
    "uname": "Eamorr3" 
} 

Jak ustawić "czytać" do 1, gdzie id = ABCDZZZZ? Używam PHP.

Próbowałem następujące polecenie:

$driverInboxes->update(array('uname'=>$uname),array('$set'=>array('messages'=>array('id'=>$id,'read'=>'1')))); 

Ale kiedy to zrobić, następuje nadpisywanie i uzyskać:

{ 
    "_id": ObjectId("4d0b9c7a8b012fe287547157"), 
    "messages": { 
    "id": "j7zwr2hzx14d3sucmvp5", 
    "read": "1" 
    }, 
    "uname": "Eamorr3" 
} 

jestem całkowicie zatrzymany. Każda pomoc doceniona.

Czy muszę wyciągnąć cały element tablicy, zmodyfikować go i ponownie wcisnąć?

Dziękujemy wcześniej,

+0

możliwy duplikat [zagnieżdżonej macierzy aktualizacji MongoDB] (http://stackoverflow.com/questions/11261521/mongodb-update-nested-array) – user956584

+0

Obecnie jest to możliwe: http://stackoverflow.com/questions/ 11261521/mongodb-update-nested-array – user956584

Odpowiedz

16

Jeśli czytać polecenia, jesteś rzeczywiście mówiąc: "UPDATE WHERE uname = Eamorr3 SET wiadomości równe tej tablicy (id = bla, czytać = 1)"

Kiedy robisz $set na messages, zasadniczo poinstruujesz go, aby wziął tablicę jako nową wartość.

Wygląda jednak na to, że próbujesz zaktualizować określoną wiadomość jako przeczytaną, która jest nieco bardziej złożona. Tak więc istnieją dwie przeszkody tutaj:

1: Ty faktycznie aktualizowanie messages.0.read

Jeśli nie array('$set' => array('messages.0.read' => 1)), będzie aktualizować poprawne element. Śledź ten łańcuch, messages jest obiektem javascript i chcesz zaktualizować właściwość 0. Właściwość 0 sama jest obiektem javascript, który zawiera właściwość read, którą chcesz zaktualizować.

Czy widzisz, jak aktualizujesz messages.0.read?

To prowadzi nas do problemu nr 2.

2: 0 jest problemem dla ciebie

Jeśli spojrzeć na drodze masz strukturze danych w Mongo, komunikaty obiekt jest bardzo sub-par. "0" i "1" działają obecnie jako "ids" i nie są zbyt użyteczne. Osobiście uporządkowałbym twoje obiekty z rzeczywistymi identyfikatorami zamiast "0" lub "1".

więc obiekty będzie wyglądać następująco:

{ 
    "_id": ObjectId("4d0b9c7a8b012fe287547157"), 
    "messages": { 
    "ABCDZZZ": { 
     "toUname": "Eamorr3", 
     "fromUname": "Eamorr2", 
     "time": 1292606586, 
     "subject": "asdf", 
     "message": "asdf", 
     "read": 0 //I want to change this to 1! 
    } 
    }, 
    "uname": "Eamorr3" 
} 

Teraz jesteś komenda zmiana staje się w ten sposób:

array('$set' => array('messages.ABCDZZZ.read' => 1))

Taka struktura sprawia, że ​​znacznie łatwiej aktualizować konkretną wiadomość lub konkretna część wiadomości.

+0

Hej, myślałem o restrukturyzacji tak, jak wspomniałeś. Myślę, że to prawdopodobnie najlepsza droga. W przeciwnym razie będę musiał przejrzeć całą tablicę, znaleźć indeks obiektów i zaktualizować. – Eamorr

+0

Zobacz także [$ elemMatch] (http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29#DotNotation%28ReachingintoObjects%29-Matchingwith24_Mem) – webjay

2

Jeśli chcesz zachować strukturę macierzy dla różnych celów, możesz użyć Positional operator. Umożliwia to korzystanie z funkcji tablicowych ($ pop, $ push, itp.), Jednocześnie umożliwiając aktualizację elementów znajdujących się w nieznanej tablicy.

Powiązane problemy