MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Compare arrays e retorne a diferença


As únicas coisas que "modificam" o documento em resposta são .aggregate() e .mapReduce() , onde o primeiro é a melhor opção.

Nesse caso, você está pedindo $setDifference que compara os "conjuntos" e retorna a "diferença" entre os dois.

Então, representando um documento com seu array:
db.collection.insert({ "b": [1, 3, 5, 6, 7, 10] })

Execute a agregação:
db.collection.aggregate([{ "$project": { "c": { "$setDifference": [ [2,3,4], "$b" ] } } }])

Que retorna:
{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4 ] }

Se você não quer "conjuntos" e, em vez disso, deseja fornecer uma matriz como [2,3,4,4] então você pode comparar com $filter e $in em vez disso, se você tiver pelo menos o MongoDB 3.4:
db.collection.aggregate([
  { "$project": {
    "c": {
      "$filter": {
        "input": [2,3,4,4],
        "as": "a",
        "cond": {
          "$not": { "$in": [ "$$a", "$b" ]  }
        }
      }
    }   
  }}
])

Ou com $filter e $anyElementTrue em versões anteriores:
db.collection.aggregate([
  { "$project": {
    "c": {
      "$filter": {
        "input": [2,3,4,4],
        "as": "a",
        "cond": {
          "$not": {
            "$anyElementTrue": {
              "$map": {
                "input": "$b",
                "as": "b",
                "in": {
                  "$eq": [ "$$a", "$$b" ]    
                }
              }    
            }
          }
        }    
      }
    }    
  }}
])

Onde ambos retornariam:
{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4, 4 ] }

O que é claro "não é um conjunto" já que o 4 foi fornecido como entrada "duas vezes" e, portanto, também é retornado "duas vezes".