No exemplo a seguir, suponha que o documento esteja na coleção db.people .
Como remover o terceiro elemento da matriz de interesses por seu índice ?
{
"_id" : ObjectId("4d1cb5de451600000000497a"),
"name" : "dannie",
"interests" : [
"guitar",
"programming",
"gadgets",
"reading"
]
}
Esta é minha solução atual:
var interests = db.people.findOne({"name":"dannie"}).interests;
interests.splice(2,1)
db.people.update({"name":"dannie"}, {"$set" : {"interests" : interests}});
Existe uma maneira mais direta?
Respostas:
Não há uma maneira direta de puxar / remover por índice de array. Na verdade, este é um problema aberto http://jira.mongodb.org/browse/SERVER-1014 , você pode votar nele.
A solução alternativa é usar $ unset e, em seguida, $ pull:
Atualização: conforme mencionado em alguns dos comentários, esta abordagem não é atômica e pode causar algumas condições de corrida se outros clientes lerem e / ou escreverem entre as duas operações. Se precisarmos que a operação seja atômica, poderíamos:
fonte
Você pode usar o
$pull
modificador deupdate
operação para remover um elemento específico em uma matriz. Caso você tenha fornecido uma consulta será semelhante a esta:Além disso, você pode considerar o uso
$pullAll
para remover todas as ocorrências. Mais sobre isso na página de documentação oficial - http://www.mongodb.org/display/DOCS/Updating#Updating-%24pullIsso não usa índice como critério para remover um elemento, mas ainda pode ajudar em casos semelhantes ao seu. IMO, usar índices para endereçar elementos dentro de um array não é muito confiável, pois mongodb não é consistente em uma ordem de elementos tão rápido quanto eu sei.
fonte
Em vez de usar o não definido (como na resposta aceita), resolvo isso definindo o campo com um valor único (ou seja, não NULL) e imediatamente puxando esse valor. Um pouco mais seguro de uma perspectiva assincrônica. Aqui está o código:
Esperançosamente, mongo resolverá isso, talvez estendendo o modificador de posição $ para suportar $ pull, bem como $ push.
fonte
Eu recomendaria usar um campo GUID (eu costumo usar ObjectID), ou um campo de incremento automático para cada subdocumento na matriz.
Com este GUID é fácil emitir um $ pull e ter certeza de que o correto será puxado. O mesmo vale para outras operações de array.
fonte
A partir de
Mongo 4.4
, o$function
operador de agregação permite aplicar uma função javascript customizada para implementar um comportamento não suportado pela linguagem de consulta MongoDB.Por exemplo, para atualizar uma matriz removendo um elemento em um determinado índice:
$function
leva 3 parâmetros:body
, que é a função a ser aplicada, cujo parâmetro é a matriz a ser modificada. A função aqui consiste simplesmente em usar splice para remover 1 elemento no índice 2.args
, que contém os campos do registro que abody
função usa como parâmetro. No nosso caso"$interests"
.lang
, que é o idioma no qual abody
função é escrita. Apenasjs
está disponível atualmente.fonte
no Mongodb 4.2, você pode fazer isso:
P é o índice do elemento que você deseja remover do array.
Se você deseja remover de P até o final:
fonte
Para pessoas que estão procurando uma resposta usando o mangusto com nodejs. É assim que eu faço.
Posso reescrever esta resposta se não entender muito bem, mas acho que está tudo bem.
Espero que isso ajude você, perdi muito tempo enfrentando esse problema.
fonte
Em vez de usar $ pull, podemos usar $ pop para remover elementos em um array por seu índice. Mas você deve subtrair 1 da posição do índice para remover com base no índice.
Por exemplo, se você deseja remover o elemento no índice 0 você deve usar -1, para o índice 1 você deve usar 0 e assim por diante ...
Consulta para remover o terceiro elemento (gadgets):
db.people.update({"name":"dannie"}, {'$pop': {"interests": 1}})
para referência: https://docs.mongodb.com/manual/reference/operator/update/pop/
fonte
$pop
só pode remover o primeiro ou o último elemento da matriz. A consulta nesta resposta não remove o terceiro elemento.