sql >> Database >  >> NoSQL >> MongoDB

MongoDB $filter

In MongoDB, de $filter aggregatiepijplijnoperator retourneert een subset van een array op basis van een opgegeven voorwaarde.

De $filter operator retourneert een array met alleen die elementen die overeenkomen met de voorwaarde, in hun oorspronkelijke volgorde.

Syntaxis

De syntaxis gaat als volgt:

{ $filter: { input: <array>, as: <string>, cond: <expression> } }

Elk veld is zoals hieronder uitgelegd.

Veld Specificatie
input Een expressie die wordt omgezet in een array.
as Dit is een optioneel veld. Het specificeert een naam voor de variabele die elk afzonderlijk element van de input vertegenwoordigt reeks. Als er geen naam is opgegeven (d.w.z. als u dit veld weglaat), wordt de variabelenaam standaard this .
cond Een expressie die wordt omgezet in een booleaanse waarde die wordt gebruikt om te bepalen of een element moet worden opgenomen in de uitvoerarray. De expressie verwijst naar elk element van de input array afzonderlijk met de variabelenaam gespecificeerd in as .

Voorbeeld

Stel dat we een verzameling hebben met de naam players met de volgende documenten

{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "player" : "Marge", "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8 ] }

Hier is een voorbeeld van het toepassen van het $filter operator om de array-elementen in de scores . te filteren veld:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 1, 2, 3 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultaat:

{ "_id" : 1, "highScores" : [ ] }
{ "_id" : 2, "highScores" : [ 17, 18 ] }
{ "_id" : 3, "highScores" : [ 15, 11 ] }

In dit voorbeeld hebben we de arrays gefilterd op alleen die elementen met een waarde groter dan 10. Alleen die waarden worden geretourneerd.

Alle waarden die kleiner zijn dan 10 worden weggelaten uit het resultaat. In het geval van het eerste document resulteert dit in een lege array.

Hier gebruikten we de as veld om de retourvariabele score een naam te geven . We verwezen vervolgens naar die variabele in de cond veld met $$score . Zoals vermeld, kunt u de as . weglaten veld, en verwijs vervolgens naar de retourvariabele met $$this . Hierover later meer.

Lege arrays

Als de array leeg is, wordt een lege array geretourneerd.

Stel dat we het volgende document in onze collectie hebben:

{ "_id" : 4, "player" : "Farnsworth", "scores" : [ ] }

Dit is wat er gebeurt als we $filter toepassen naar die array:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 4 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultaat:

{ "_id" : 4, "highScores" : [ ] }

Verkeerd type

$filter toepassen naar een veld dat geen array bevat, retourneert een fout.

Voorbeeld:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 4 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$player",
              as: "player",
              cond: { $gt: [ "$$player", 10 ] }
          }
        }
    }
  }
])

Resultaat:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "input to $filter must be an array not string",
	"code" : 28651,
	"codeName" : "Location28651"
} : aggregate failed :
[email protected]/mongo/shell/utils.js:25:13
[email protected]/mongo/shell/assert.js:18:14
[email protected]/mongo/shell/assert.js:618:17
[email protected]/mongo/shell/assert.js:708:16
[email protected]/mongo/shell/db.js:266:5
[email protected]/mongo/shell/collection.js:1046:12
@(shell):1:1

Null-waarden

Als het veld null . bevat in plaats van een array is het resultaat null .

Stel je voor dat we het volgende document in de collectie hebben:

{ "_id" : 5, "player" : "Meg", "scores" : null }

Dit is wat er gebeurt als we $filter toepassen naar de scores veld:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 5 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultaat:

{ "_id" : 5, "highScores" : null }

Niet-bestaand veld

$filter toepassen naar een veld dat niet bestaat resulteert in null wordt geretourneerd.

Voorbeeld:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 5 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$name",
              as: "name",
              cond: { $gt: [ "$$name", 10 ] }
          }
        }
    }
  }
])

Resultaat:

{ "_id" : 5, "highScores" : null }

De variabelenaam is optioneel

In de vorige voorbeelden gebruik ik de as veld om een ​​naam aan de variabele toe te wijzen.

Zoals gezegd, de as veld is optioneel. Als u dit veld weglaat, wordt de variabelenaam standaard this .

Hier is een voorbeeld:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 1, 2, 3 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              cond: { $gt: [ "$$this", 10 ] }
          }
        }
    }
  }
])

Resultaat:

{ "_id" : 1, "highScores" : [ ] }
{ "_id" : 2, "highScores" : [ 17, 18 ] }
{ "_id" : 3, "highScores" : [ 15, 11 ] }

Dit is hetzelfde als het eerste voorbeeld, behalve dat we in dit voorbeeld de as . weglaten veld, en verwijs daarom naar de variabele met $$this .


  1. Meerdere waarden atomair uit de Redis-gegevensstructuur halen?

  2. Redis 10x meer geheugengebruik dan data

  3. Zoek sleutel op waarde

  4. Hoe moet ik verbinding maken met een Redis-instantie vanuit een AWS Lambda-functie?