2013-04-14 12 views
16

Mam schemat dokumentu w MongoDB, który wygląda tak:Aktualizacja wielu zagnieżdżonych tablicy w MongoDB

{ 
    _id: 1 
    tags: [{ 
     tag: 'foo' 
     links: [{ 
      link: 'http:www.google.com' 
      date: '123' 
     }] 
    }] 
} 

próbuję wcisnąć link do tablicy „linki”, który będzie przypisany do dokumentu.

Moje pierwsze zapytanie ...

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo'}}}, 
    {upsert: true} 
) 

Daje mi to tworzy tag (jeśli nie istnieje)

{ "_id" : 1, "tags" : [ { "tag" : "foo" } ] } 

Następnie postępuj że z tego zapytania ...

db.userlinks.update (
    {_id: 1, tags: {tag: 'foo', links: {$nin: [{link: 'http://www.google.com'}]}}}, 
    {$push: {tags: {tag: 'foo', links: {link: 'http://www.google.com', date: '123'}}}}, 
    {upsert: true} 
) 

Ale otrzymuję ten błąd: "nie można stosować $ Push/$ pushAll modyfikator do braku tablicy"

Jestem prawie pewien, że problem jest w "aktualizacji" składnik mojego drugiego zapytania, ale nie jestem pewien, jak to naprawić. Każda pomoc będzie doceniona.

EDIT

Moje pierwsze zapytanie jest teraz ... (dzięki Joe)

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

Moje drugie zapytanie jest teraz ...

db.userlinks.update (
    {_id: 1, 'tags.tag': 'foo'}, 
    {$push: {'tags.$.links': {link: 'http://www.google.com', date: '123'} } } 
) 

Który skutecznie odpycha link do tablica "łączy", ale pozwala również na duplikaty. Nie mogę pozwolić na duplikowanie linków. $ addToSet rodzaj prac, jednak jeśli data się zmieni, to nadal wstawi zduplikowany link.

Czy istnieje sposób sprawdzenia istnienia łącza w części "zapytanie" mojego drugiego zapytania, czy zamiast tego tylko addToSet, jeśli pewne pola są zgodne?

+0

Nie możesz. rozważ zmianę schematu? –

+3

Nie chcę zmieniać schematu, ponieważ jest on dokładnie taki, jaki jest jego format wyjściowy, co oznacza, że ​​nie muszę wykonywać żadnych danych, gdy tylko wydobędę go z bazy danych. Myślałem, że to miał być główny powód używania Mongodb? Możliwość modelowania obiektów bezpośrednio do bazy danych iz bazy danych. –

Odpowiedz

18

W końcu to dostałem ... chociaż jeśli ktoś może zobaczyć lepszy sposób, aby to zrobić, proszę dodać go jako odpowiedź.

// create the userlinks collection if it doesn't exist 
// also add a tag 'foo' into it, but only if the tag doesn't exist 
db.userlinks.update (
    {_id: '1', 'tags.tag': {$nin: ['foo']}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

// add a link into the 'foo' tag, but only if the link doesn't exist 
db.userlinks.update(
    {_id: '1', 'tags.tag': 'foo', 'tags.links.link': {$nin: ['http://foobar.com']}}, 
    {$push: {'tags.$.links': {link: 'http://foobar.com', date: '15'} } } 
) 
+1

Interesujące. Dziękuję za aktualizację. Możesz zaznaczyć własną odpowiedź jako zaakceptowaną. –

+0

@Harley: Jak zaktualizować datę do 20, jeśli znamy _id, "tags.tags" i "tags.links.link" ... db.doc.update ({_ id:, 'tags.tags:,' tags.links.link ':}, {$ inc: {' tags.links. $. date ': 20}}) nie działa, ponieważ mamy dwie tablice. Proszę o pomoc. –

+0

Przepraszam, Praveen, nie pracowałem z Mongo od czasu, kiedy napisałem ten post i zasadniczo zapomniałem zawiłości języka zapytań, których się obawiam. Być może otworzyć nowe pytanie? –

1

Być może zmienić swoją pierwszą kwerendę do:

db.userlinks.update (
    {_id: 1, tags: {$nin: [{tag:'foo'}]}}, 
    {$push: {'tags': {tag:'foo', links:[]}}}, 
    {upsert: true} 
) 

dolarów operacji pchania powinny dotyczyć tylko linki, a nie tagu.

{$push: {'tags.links': {link: 'http://www.google.com', date: '123'} } }, 
+0

To zainicjowało "linki" do pustej tablicy, co jest dobre i prawdopodobnie coś, czego potrzebowałem, jednak moje drugie zapytanie wciąż wywołuje ten sam błąd. –

+0

Zaktualizowano odpowiedź. –

+0

Niestety, nadal mam ten sam błąd, używając tego drugiego zapytania: db.userlinks.update ( {_id: 1, tagi: {tag: 'foo', linki: {$ nin: [{link: 'google. com '}]}}}, {$ push: {' tags.links ': {link:' google.com ', data:' 123 '}}}, {upsert: true} ) –

Powiązane problemy