$and
$and
executa uma operaçãoAND
lógica em uma array de uma ou mais expressões (<expression1>
,<expression2>
e assim por diante) e seleciona os documentos que satisfazem todas as expressões.Observação
O MongoDB fornece uma operação
AND
implícita ao especificar uma lista de expressões separada por vírgula.
Compatibilidade
Você pode utilizar o $and
para implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
O $and
tem a seguinte sintaxe:
{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
Comportamento
Ao avaliar as cláusulas na expressão $and
, o otimizador de query do MongoDB considera quais índices estão disponíveis que podem ajudar a satisfazer as cláusulas da expressão $and
ao selecionar o melhor plano para executar.
Para permitir que o mecanismo de consulta otimize as consultas, o $and
lida com erros como segue:
Se qualquer expressão fornecida para
$and
causar um erro quando avaliada sozinha, o$and
contendo a expressão pode causar um erro, mas um erro não é garantido.Uma expressão fornecida após a primeira expressão fornecida para
$and
pode causar um erro mesmo se a primeira expressão avaliar parafalse
.
Por exemplo, a seguinte consulta sempre produz um erro se $x
for 0
:
db.example.find( { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } )
A consulta a seguir, que contém várias expressões fornecidas para $and
, pode gerar um erro se houver algum documento em que $x
seja 0
:
db.example.find( { $and: [ { x: { $ne: 0 } }, { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } ] } )
A maioria das linguagens de programação e drivers, incluindo o MongoDB Shell (mongosh
), não permite a criação de objetos com chaves duplicadas no mesmo nível de objeto. Por exemplo, considere esta query:
db.inventory.find( { price: { $in: [ 7.99, 3.99 ], $in: [ 4.99, 1.99 ] } } )
A query acima não é construída corretamente porque o nome do campo price
possui operadores duplicados no mesmo nível de objeto. Como resultado, a query enviada ao servidor é diferente daquela que era esperada. Para que a query funcione como esperado, use um operador AND
explícito:
db.inventory.find( { $and: [ { price: { $in: [ 7.99, 3.99 ] } }, { price: { $in: [ 4.99, 1.99 ] } } ] } )
Esta query verifica explicitamente se ambas as condições estão satisfeitas: a array price
deve incluir pelo menos um valor de cada conjunto $in
. Para mais informações sobre como lidar com esses cenários, acesse a seção Exemplos.
Exemplos
Queries $and com várias expressões especificando o mesmo campo
Considere esta query:
db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
A query seleciona todos os documentos na collection inventory
onde:
o valor do campo
price
não é igual a1.99
eo campo
price
existe.
Você pode simplificar esta query combinando as expressões de operador para o campo price
em um único objeto de query com um AND
implícito aninhado:
db.inventory.find( { price: { $ne: 1.99, $exists: true } } )
Às vezes, tais regravações não são possíveis, especialmente ao lidar com condições duplicadas no mesmo campo. Por exemplo:
db.inventory.find( { status: { $ne: "closed", $ne: "archived" } } )
A query acima não é construída corretamente porque utiliza o operador $ne
mais de uma vez no mesmo nome de campo status
no mesmo nível de objeto. Neste caso, o operador $nin
oferece uma solução mais eficaz:
db.inventory.find( { status: { $nin: [ "closed", "archived" ] } } )
A forma como você regrava uma query depende da semântica desejada para o seu caso de uso. Considere a seguinte query:
db.inventory.find( { $and: [ { status: "new" }, { status: "processing" } ] } )
Se você quiser encontrar documentos onde status
seja new
ou processing
, você pode usar o operador $in
:
db.inventory.find( { status: { $in: [ "new", "processing" ] } } )
Se o campo status
for uma array [ "new", "processing" ]
e você quer verificar se o documento contém tanto os valores new
quanto processing
, use o operador $all
:
db.inventory.find( { status: { $all: [ "new", "processing" ] } } )
Nesse contexto, essa query é semanticamente equivalente a AND
, mas $all
geralmente é mais clara ao fazer query de campos de array.
Semelhante aos nomes de campo duplicados, as mesmas considerações se aplicam para operadores duplicados usados na query.