2015-06-11 11 views
6

Sembra che si stia verificando un problema durante l'accesso al contenuto di un array nidificato all'interno di un array in un documento mongodb. Ho problemi di accesso prima matrice "gruppi" con una query come la seguente ...MongoDB: aggiornamento di un array nell'array

db.orgs.update({_id: org_id, "groups._id": group_id} , {$set: {"groups.$.name": "new_name"}}); 

Dove incontrato difficoltà è quando si tenta di modificare le proprietà di un elemento della matrice "caratteristiche" annidato all'interno la matrice "gruppo".

Ecco ciò che un documento di esempio appare come

 { 
     "_id" : "v5y8nggzpja5Pa7YS", 
     "name" : "Example", 
     "display_name" : "EX1", 
     "groups" : [ 
      { 
       "_id" : "s86CbNBdqJnQ5NWaB", 
       "name" : "Group1", 
       "display_name" : "G1", 
       "features" : [ 
        { 
         _id  : "bNQ5Bs8BWqJn6CdNa" 
         type  : "blog", 
         name  : "[blog name]" 
         owner_id : "ga5YgvP5yza7pj8nS" 
        }, 
       ] 
      }, 
     ] 
    }, 

E questa è la query ho cercato di utilizzare.

db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "qBX3KDrtMeJGvZWXZ", "groups.features._id":"bNQ5Bs8BWqJn6CdNa" }, {$set: {"groups.$.features.$.name":"New Blog Name"}}); 

Si ritorna con un messaggio di errore:

WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 2, 
     "errmsg" : "Too many positional (i.e. '$') elements found in path 'groups.$.features.$.name'" 
    } 
}) 

Sembra che mongo non supporta modifica di array annidati all'interno array attraverso l'elemento di posizione?

C'è un modo per modificare questo array senza prendere in considerazione tutto, modificarlo e quindi rimetterlo? Con più annidamenti come questo è prassi normale creare una nuova collezione? (Anche se i dati sono necessari solo quando sono necessari i dati principali) Devo cambiare la struttura del documento in modo che il secondo array annidato sia un oggetto e accedervi tramite chiave? (Dove la chiave è un valore intero che può agire come un "_id")

groups.$.features.[KEY].name 

Ciò che è considerato il modo "corretto" per fare questo?

risposta

3

Dopo ulteriori ricerche, sembra che l'unico modo per modificare l'array all'interno di un array sia con una logica esterna per trovare l'indice dell'elemento che si desidera modificare. Fare ciò richiederebbe ogni modifica di avere una query di ricerca per individuare l'indice e quindi una query di aggiornamento per modificare l'array. Questo non sembra il modo migliore.

Link to a 2010 JIRA case requesting multiple positional elements...

Dato che io sarò sempre conoscere l'ID della caratteristica, ho scelto di rivedere la mia struttura del documento.

 { 
    "_id" : "v5y8nggzpja5Pa7YS", 
    "name" : "Example", 
    "display_name" : "EX1", 
    "groups" : [ 
     { 
      "_id" : "s86CbNBdqJnQ5NWaB", 
      "name" : "Group1", 
      "display_name" : "G1", 
      "features" : { 
       "1" : { 
         type  : "blog", 
         name  : "[blog name]" 
         owner_id : "ga5YgvP5yza7pj8nS" 
       }, 
      } 
     }, 
    ] 
}, 

Con la nuova struttura, modifiche possono essere effettuate nel seguente modo:

db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "s86CbNBdqJnQ5NWaB"}, {$set: {"groups.$.features.1.name":"Blog Test 1"}});