Como remover um elemento de um array duplamente nested em um documento MongoDB

Eu tenho uma estrutura de documento algo ao longo das linhas do seguinte:

{ "_id" : "777", "someKey" : "someValue", "someArray" : [ { "name" : "name1", "someNestedArray" : [ { "name" : "value" }, { "name" : "delete me" } ] } ] } 

Desejo excluir o elemento da matriz aninhada com o valor “delete me”.

Eu sei que posso encontrar documentos que correspondam a esta descrição usando expressões aninhadas $ elemMatch. Qual é a syntax da consulta para remover o elemento em questão?

Para excluir o item em questão, você realmente usará uma atualização. Mais especificamente, você fará uma atualização com o comando $pull que removerá o item da matriz.

 db.temp.update( { _id : "777" }, {$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}} ) 

Há um pouco de “mágica” acontecendo aqui. O uso de .0 indica que sabemos que estamos modificando o 0º item de someArray . Usar {"name":"delete me"} indica que sabemos os dados exatos que planejamos remover.

Esse processo funciona bem se você carregar os dados em um cliente e depois executar a atualização. Esse processo funciona menos bem se você quiser fazer consultas “genéricas” que executam essas operações.

Eu acho que é mais fácil simplesmente reconhecer que a atualização de matrizes de sub-documentos geralmente requer que você tenha o original na memory em algum momento.


Em resposta ao primeiro comentário abaixo, você provavelmente pode ajudar sua situação alterando um pouco a estrutura de dados

 "someObjects" : { "name1": { "someNestedArray" : [ { "name" : "value" }, { "name" : "delete me" } ] } } 

Agora você pode fazer {$pull : { "someObjects.name1.someNestedArray" : ...

Aqui está o problema com sua estrutura. O MongoDB não tem suporte muito bom para manipular “sub-arrays”. Sua estrutura tem uma matriz de objects e esses objects contêm matrizes de mais objects.

Se você tem a seguinte estrutura, você vai ter dificuldade em usar coisas como $pull :

 array [ { subarray : array [] }, { subarray : array [] }, ] 

Se sua estrutura se parece com isso e você quer atualizar o subarray você tem duas opções:

  1. Mude sua estrutura para que você possa aproveitar $pull .
  2. Não use $pull . Carregue o object inteiro em um cliente e use findAndModify .

Como @Melkor comentou (provavelmente deveria ser uma resposta como ele mesmo),

Se você não souber o uso do índice:

 {_id: TheMainID, theArray._id: TheArrayID}, {$pull: {"theArray.$.theNestedArray": {_id: theNestedArrayID}}}