Digamos que temos os seguintes documentos em nossa coleção:
{ "_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ] }
{ "_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ] }
{ "_id" : ObjectId("5759658e654456bf4a014d03"), "a" : [ 0, 8, 432, 9, 34, -3 ] }
{ "_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ] }
e a seguinte matriz de entrada e
n = 2
var inputArray = [1, 3, 0];
Podemos retornar aqueles documentos onde o campo array contém pelo menos n elementos de um determinado array usando o framework de agregação.
O
$match
seleciona apenas os documentos com comprimento do array maior ou igual a n
. Isso reduz a quantidade de dados a serem processados no pipeline. O
$redact
operador de pipeline usa um processamento de condição lógica usando o $cond
operador e as operações especiais $$KEEP
para "manter" o documento onde a condição lógica é verdadeira ou $$PRUNE
para "descartar" o documento onde a condição é falsa. No nosso caso, a condição é
$gte
que retorna true se o $size
da interseção dos dois arrays, que calculamos usando o $setIntersection
operador é maior ou igual a 2
. db.collection.aggregate(
[
{ "$match": { "a.1": { "$exists": true } } },
{ "$redact": {
"$cond": [
{ "$gte": [
{ "$size": { "$setIntersection": [ "$a", inputArray ] } },
2
]},
"$$KEEP",
"$$PRUNE"
]
}}
]
)
que produz:
{ "_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ] }
{ "_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ] }
{ "_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ] }