I enhver virksomhed er data dit største aktiv. Ved at analysere data kan du træffe beslutninger om kundetendenser og forudsigelse af adfærd. Dette øger virksomhedens rentabilitet og effektiv beslutningstagning.

Uden databasesoftware ville en simpel opgave som at finde gennemsnittet af alle værdierne i et system fuld af poster være kedelig. Heldigvis har databaser gjort det nemmere og hurtigere at analysere data med funktioner og operatører.

Denne artikel vil kaste lidt lys over de operatører, der bruges i MongoDB-databasesoftwaren.

Hvad er MongoDB-operatorer?

MongoDB er en NoSQL-databasesoftware, der håndterer dokumentorienteret information.

En af MongoDB’s vigtigste funktioner er dens hastighed. For at returnere forespørgsler hurtigere kan MongoDB bruge operatører til at udføre specifikke funktioner.

Operatorer er specielle symboler, der hjælper compilere med at udføre matematiske eller logiske opgaver. MongoDB tilbyder flere typer af operatører til at interagere med databasen.

MongoDB Operatortyper

Der findes ni typer af operatører, som hver især er opkaldt efter deres funktion. Logiske operatører bruger f.eks. logiske operationer. For at udføre dem skal du bruge et specifikt nøgleord og følge syntaksen. De er dog ret nemme at følge!

Når du når slutningen af artiklen vil du være i stand til at lære det grundlæggende om hver enkelt operatør og dens funktioner.

Logiske operatorer

Logiske operatorer bruges ofte til at filtrere data på baggrund af de givne betingelser. De giver også mulighed for at evaluere mange betingelser, hvilket vi vil diskutere nærmere.

Nedenfor er der nogle få logiske operatorer, som du kan bruge:

$og

En “og”-betingelse udfører en logisk “og”-operation på et array af to eller flere udtryk. Den udvælger de dokumenter, hvor alle betingelserne i udtrykkene er opfyldt.

Dette er standardsyntaksen for udtrykket $and:

{ $and: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
db.inventory.find( { $and: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

$or

En “or”-betingelse udfører en logisk “or”-operation på et array af to eller flere udtryk. Den udvælger de dokumenter, hvor mindst et af udtrykkene er sandt.

Dette er standardsyntaksen for udtrykket $or:

{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }.

Hvis vi f.eks. ønsker at udvælge dokumenter, hvor prisen er 10 USD eller mængden er mindre end 15, kan vi indtaste følgende forespørgsel:

db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )

Vi behøver ikke at begrænse udtrykket til to kriterier – vi kan tilføje flere. F.eks. kan nedenstående forespørgsel udvælge de dokumenter, hvor prisen er lig med 10 USD, mængden er under 15, eller tagget er stationært:

db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 }, { tag: "stationary" }] } )

Når disse klausuler køres, udfører MongoDB enten en samlingsscanning eller en indeksscanning. Hvis alle indekser understøtter klausulerne, bruger MongoDB indekser til at kontrollere et $or udtryk. Ellers bruger den i stedet en samlingsscanning.

Men hvis du ønsker at teste kriterierne i det samme felt, kan du bruge operatoren $in i stedet for operatoren $or. Hvis du f.eks. vil have en samling dokumenter, hvor mængden enten er 10 eller 20, skal du måske køre nedenstående $in forespørgsel i stedet:

db.inventory.find ( { quantity: { $in: [20, 50] } } )

Vi kommer nærmere ind på operatoren $in senere.

$nor

Denne operatør udfører en logisk “nor”-operation på et array ved hjælp af et eller flere udtryk. Derefter udvælger den de dokumenter, der ikke opfylder forespørgselsudtrykkene. I enklere vendinger gør den det modsatte af betingelsen $or.

Dette er den generelle syntaks:

{ $nor: [ { <expression1> }, { <expression2> }, ...  { <expressionN> } ] }

Lad os se på følgende forespørgsel:

db.inventory.find( { $nor: [ { price: 3.99 }, { sale: true } ]  } )

Denne forespørgsel udvælger de dokumenter, der indeholder:

  • en værdi i prisfeltet, der ikke er lig med 3,99 USD, og en salgsværdi, der ikke er lig med true, eller
  • en værdi i prisfeltet, der ikke er lig med 3,99 USD, og et tomt eller manglende salgsfelt, eller
  • intet prisfelt og et udsalgsfelt, der ikke er lig med true, eller
  • hverken prisfelt eller udsalgsfelt er udfyldt eller til stede.

$not

Denne operatør udfører en logisk “not”-operation på et array for det angivne udtryk. Derefter udvælges de dokumenter, der ikke svarer til forespørgselsudtrykket. Dette omfatter de dokumenter, der ikke indeholder feltet.

Dette er den generelle syntaks:

{ field: { $not: { <operator-expression> } } }

Tag f.eks. følgende forespørgsel:

db.inventory.find( { price: { $not: { $lt: 3.99 } } } )

Denne forespørgsel vil vælge de dokumenter, der indeholder:

  • et prisfelt, hvis værdi er større end eller lig med 3,99 USD, og
  • et prisfelt er ikke udfyldt eller findes ikke.

Sammenligningsoperatorer

Sammenligningsoperatorer kan bruges til at sammenligne værdier i et eller flere dokumenter.

Nedenfor er et kodeeksempel på en simpel lageropsamling for et supermarked:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] },
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] },
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] },
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] },
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] },
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Vi bruger dette eksempel, mens vi beskriver hver enkelt sammenligningsoperator i det følgende.

Lig med ($eq)

Denne operatør matcher værdier, der er lig med den givne værdi:

{ <field>: { $eq: <value> } }

Hvis vi f.eks. ønsker at hente et bestemt dokument fra inventaropsamlingen med den nøjagtige mængdeværdi “20”, skal vi indtaste følgende kommando:

db.inventory.find( { qty: { $eq: 20 } } )

Forespørgslen ville returnere følgende:

{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }, 
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Større end ($gt)

Denne operator passer til, hvis værdierne er større end den angivne værdi:

{ field: { $gt: value } }

I dette eksempel henter vi de dokumenter, hvor mængden er større end 15:

db.inventory.find({"qty": { $gt: 15}})

Forespørgslen ville give følgende:

{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Mindre end ($lt)

Denne operator passer til, hvis værdierne er mindre end den angivne værdi:

{ field: { $lt: value } }

Lad os finde de dokumenter, hvis antal er mindre end 25:

db.inventory.find({"qty": { $lt: 25}})

Forespørgslen vil give følgende:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

Større end eller lig med ($gte)

Denne operatør passer, når værdierne er større end eller lig med den angivne værdi:

{ field: { $gte: value } }

I dette eksempel henter vi de dokumenter, hvor mængden er større end eller lig med 25:

db.inventory.find({"qty": { $gte: 25}})

Denne forespørgsel ville give følgende:

{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }

Mindre end eller lig med ($lte)

Denne operator passer kun, hvis værdierne er mindre end eller lig med den angivne værdi:

{ field: { $lte: value } }

Lad os finde de dokumenter med en mængde, der er mindre end eller lig med 25.

db.inventory.find({"qty": { $lte: 25}})

Vi kan forvente, at denne forespørgsel returnerer følgende:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 2, item: { name: "banana", code: "123" }, qty: 20, tags: [ "B" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 5, item: { name: "pears", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }

I ($in)

Denne operatør returnerer de dokumenter, der svarer til de angivne værdier:

{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }

Værdien af et felt er lig med enhver værdi i det angivne array. Hvis du f.eks. vil hente dokumenterne med værdierne “30” og “15” i inventarsamlingen, skal du gøre dette:

db.inventory.find({ "qty": { $in: [30, 15]}})

Udgangen ville være:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }

Ikke i ($nin)

Denne operatør returnerer de dokumenter, der ikke matcher de givne værdier. Her er den grundlæggende syntaks for operatoren $nin:

{ field: { $nin: [ <value1>, <value2> ... <valueN> ]

$nin udvælger de dokumenter, hvor:

  • feltets værdi er ikke i det angivne array, eller
  • feltet findes ikke.

Hvis feltet indeholder arrays, udvælges arrays, hvor der ikke findes noget element, der er angivet i værdiafsnittet. Vi ønsker f.eks. at vælge de dokumenter, hvor mængden ikke er lig med hverken 20 eller 15.

Derudover matcher den også dokumenter, der ikke har et mængdefelt:

db.inventory.find({ "qty": { $nin: [ 20, 15 ]}})

Resultatet ville være:

{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Not Equal ($ne)

Operatoren $ne returnerer de dokumenter, hvor den angivne værdi ikke er lig med hinanden:

{ $ne: value } }

Lad os for eksempel sige, at vi ønsker at vælge alle dokumenter, hvor mængden ikke er lig med 20:

db.inventory.find( { qty: { $ne: 20 } } )

Resultatet ville være:

{ _id: 1, item: { name: "apple", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }
{ _id: 3, item: { name: "spinach", code: "456" }, qty: 25, tags: [ "A", "B" ] }
{ _id: 4, item: { name: "lentils", code: "456" }, qty: 30, tags: [ "B", "A" ] }
{ _id: 6, item: { name: "strawberry", code: "123" }, tags: [ "B" ] }

Af ovenstående output kan vi se, at forespørgslen vil vælge dokumenter, der ikke har et mængdefelt.

Operatorer for elementer

Med elementforespørgselsoperatorerne kan dokumenter identificeres ved hjælp af dokumentets felter. Elementoperatorer består af $exist og $type.

$exists

Denne operator matcher dokumenter, der har et angivet felt. Operatoren har en boolsk værdi, som kan være enten true eller false.

Hvis den er angivet som true, matcher den de dokumenter, der indeholder det pågældende felt, herunder dokumenter, hvor feltværdien er nul. Hvis <boolean> er false, returnerer forespørgslen kun de dokumenter, der ikke indeholder feltet.

Her er standardsyntaksen:

{ field: { $exists: <boolean> } })

Lad os tage et eksempel, hvor vi har indsamlingsdata for et array ved navn “bagofmarbles”, hvor hver pose indeholder kugler af forskellige farver:

{ red: 5, green: 5, blue: null }
{ red: 3, green: null, blue: 8 }
{ red: null, green: 3, blue: 9 }
{ red: 1, green: 2, blue: 3 }
{ red: 2, blue: 5 }
{ red: 3, green: 2 }
{ red: 4 }
{ green: 2, blue: 4 }
{ green: 2 }
{ blue: 6 }

Lad os sige, at vi ønsker en forespørgsel, der kun returnerer de poser, hvor der findes røde kugler. Det betyder, at vi skal indtaste den boolske værdi som true. Lad os tage et kig:

db.bagofmarbles.find( { red: { $exists: true } } )

Resultaterne ville bestå af de dokumenter, der indeholder feltet “red”, selv om værdien var null. Derimod ville de ikke bestå af de dokumenter, hvor feltet “red” slet ikke eksisterede:

{ red: 5, green: 5, blue: null }
{ red: 3, green: null, blue: 8 }
{ red: null, green: 3, blue: 9 }
{ red: 1, green: 2, blue: 3 }
{ red: 2, blue: 5 }
{ red: 3, green: 2 }
{ red: 4 }

Hvis vi kun ville have de poser, hvor røde kugler ikke engang findes som felt, kan vi indtaste nedenstående forespørgsel:

db.bagofmarbles.find( { red: { $exists: false} )

Resultaterne vil bestå af de dokumenter, der ikke indeholder feltet “red”:

{ green: 2, blue: 4 }
{ green: 2 }
{ blue: 6 }

$type

Denne operatør matcher dokumenter i henhold til den angivne felttype. Dette er nyttigt, når du har meget ustrukturerede data, eller når datatyperne ikke er forudsigelige. Disse felttyper er specificerede BSON-typer og kan defineres enten ved hjælp af typenummer eller alias.

Dette er den generelle syntaks for $type:

{ field: { $type: <BSON type> } }

Lad os sige, at vi har en adressebog, der indeholder nedenstående dokumenter:

db={
  addressBook: [
    {
      "_id": 1,
      address: "2100 Jupiter Spot",
      zipCode: "9036325"
    },
    {
      "_id": 2,
      address: "25 Moon Place",
      zipCode: 26237
    },
    {
      "_id": 3,
      address: "2324 Neptune Ring",
      zipCode: NumberLong(77622222)
    },
    {
      "_id": 4,
      address: "33 Saturns Moon",
      zipCode: NumberInt(117)
    },
    {
      "_id": 5,
      address: "1044 Venus Lane",
      zipCode: [
        "99883637232",
        "73488976234"
      ]
    }
  ]
}

Hvis vi ser på ovenstående dokumenter, har postnummeret forskellige datatyper. Dette omfatter lange, dobbelte, hele tal og stringværdier.

Hvis vi kun vil have de dokumenter, der har en bestemt datatype som postnummer – lad os tage string i dette tilfælde – skal vi indtaste følgende forespørgsel i compileren:

db.addressBook.find({
  "zipCode": {
    $type: "string"
  }
})

Dette ville give følgende dokumenter tilbage:

[
  {
    "_id": 1,
    "address": "2100 Jupiter Spot",
    "zipCode": "9036325"
  },
  {
    "_id": 5,
    "address": "1044 Venus Lane",
    "zipCode": [
      "99883637232",
      "73488976234"
    ]
  }
]

Derudover er der en “number”-type, som indeholder alle long-, integer- eller double-værdier som et array, der indeholder et element af de angivne typer:

db.addressBook.find( { "zipCode" : { $type : "number" } } )

Output:

[
{
      "_id": 2,
      address: "25 Moon Place",
      zipCode: 26237
    },
    {
      "_id": 3,
      address: "2324 Neptune Ring",
      zipCode: NumberLong(77622222)
    },
    {
      "_id": 4,
      address: "33 Saturns Moon",
      zipCode: NumberInt(117)
    }
]

Hvis dokumenterne har en array-felttype, returnerer operatoren $type de dokumenter, hvor mindst ét array-element svarer til den type, der er angivet til operatoren.

Array-operatorer

MongoDB består også af array-operatører til at forespørge dokumenter, der indeholder arrays.

Der er tre primære operatorer: $all, , $elemMatch og $size. Vi vil diskutere hver enkelt i detaljer nedenfor.

$all

Operatoren $all vælger de dokumenter, hvor et felts værdi er et array, der indeholder de angivne elementer:

{ : { $all: [ <value1> , <value2> ... ] } }

Lad os f.eks. sige, at vi har en samling dokumenter for en tøjbutik med følgende under inventar.

{
   _id: ObjectId("5234cc89687ea597eabee675"),
   code: "shirt",
   tags: [ "sale", "shirt", "button", "y2k", "casual" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 45, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
},

{
   _id: ObjectId("5234cc8a687ea597eabee676"),
   code: "pant",
   tags: [ "y2k", "trendy", "shine" ],
   qty: [
          { size: "6", num: 100, color: "green" },
          { size: "6", num: 50, color: "blue" },
          { size: "8", num: 100, color: "brown" }
        ]
},

{
   _id: ObjectId("5234ccb7687ea597eabee677"),
   code: "pant2",
   tags: [ "trendy", "shine" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 100, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
},

{
   _id: ObjectId("52350353b2eff1353b349de9"),
   code: "shirt2",
   tags: [ "y2k", "trendy" ],
   qty: [
          { size: "M", num: 100, color: "green" }
        ]
}

Vi ønsker at hente alle dokumenter (i dette tilfælde tøj) fra lageret, der er knyttet til tagsene “trendy” og “y2k”. Nedenstående forespørgsel anvender operatoren $all, hvor værdien af feltet tags er et array, hvis elementer omfatter “y2k” og “trendy”:

db.inventory.find( { tags: { $all: [ "y2k", "trendy" ] } } )

Ovenstående forespørgsel returnerer følgende:

{
   _id: ObjectId("5234cc8a687ea597eabee676"),
   code: "pant",
   tags: [ "y2k", "trendy", "shine" ],
   qty: [
          { size: "6", num: 100, color: "green" },
          { size: "6", num: 50, color: "blue" },
          { size: "8", num: 100, color: "brown" }
        ]
}

{
   _id: ObjectId("52350353b2eff1353b349de9"),
   code: "shirt2",
   tags: [ "y2k", "trendy" ],
   qty: [
          { size: "M", num: 100, color: "green" }
        ]
}

Fra ovenstående eksempel finder vi også, at operatoren $all simpelthen udfører den samme funktion som operationen $and.

Alternativt kunne vi bruge nedenstående forespørgsel, som ville give et lignende output som ovenstående:

db.inventory.find({
  $and: [
    {
      tags: "y2k"
    },
    {
      tags: "trendy"
    }
  ]
})

$elemMatch

Operatoren $elemMatch matcher dokumenter, der indeholder et array-felt med mindst ét element, der matcher alle de angivne forespørgselskriterier:

{ : { $elemMatch: { <query1>, <query2>, ... } } }

Vi kan bruge sammenligningsoperatorer som $lte og $gte, men hvis vi kun angiver en enkelt forespørgselsbetingelse inden for $elemMatch, og ikke bruger $not eller $ne -operatorerne, kan vi udelade at bruge $elemMatch, da det i det væsentlige ville udføre den samme funktion.

Der er et par andre ting, som man skal være opmærksom på, når man bruger denne operator, især:

  • Du kan ikke angive et $where -udtryk i en $elemMatch -operation.
  • Du kan ikke angive et $text forespørgselsudtryk i en $elemMatch -operation.

Vi har f.eks. følgende dokumenter i samlingen af elevresultater:

{ _id: 1, results: [ 92, 89, 98 ] }
{ _id: 2, results: [ 85, 99, 99 ] }

Følgende forespørgsel matcher kun de dokumenter, hvor resultatmatrixen indeholder mindst ét element, der både er større end eller lig med 90 og mindre end 95:

db.studentresults.find(  { results: { $elemMatch: { $gte: 90, $lt: 95 } } })

Vores forespørgsel returnerer følgende dokument, da elementet 92 både er større end eller lig med 90 og er mindre end 95:

{ "_id" : 1, "results" :[ 92, 89, 98 ] }

$size

Operatoren $size returnerer de dokumenter, hvor arrayets størrelse svarer til det antal elementer, der er angivet i argumentet:

{ field: { $size: value } }

Her er et eksempel:

db.collection.find( { field: { $size: 2 } });

Dette ville returnere alle dokumenter i den angivne samling, hvor feltet er et array med 2 elementer: { field: [ orange, apple] } og { field: [ blue, red] }, men ikke { field: blue} eller { field: [ raspberry, lemon, grapefruit ] }.

Men mens vi kan indtaste den specifikke værdi som størrelse, kan vi ikke angive værdimængder som størrelse.

Geospatiale operatorer

MongoDB giver dig mulighed for at gemme geospatiale data i form af GeoJSON-typer. GeoJSON er et åbent standardformat baseret på JavaScript-objektnotationen, der kan repræsentere geografiske elementer og understøtte ikke-geografiske attributter. Der er to typer geospatiale operatorer, som vi vil tale om i denne artikel: geometri-specifikatorer og forespørgselsvælgere.

$geometri

Denne operatør nævner GeoJSON-geometri til brug med følgende geospatiale forespørgselsoperatorer: $geoIntersects, , $geoWithin,$nearSphere og $near. $geometry udnytter EPSG:4326 som standardkoordinatreferencesystem (CRS).

Hvis du vil nævne GeoJSON-objekter med standard CRS, kan du bruge følgende uddrag for $geometry:

$geometry: {
   type: "<GeoJSON object type>",
   coordinates: [ <coordinates> ]
}

Hvis du vil nævne en enkeltringet GeoJSON-polygon med et skræddersyet MongoDB CRS, kan du bruge følgende uddrag (du kan kun bruge dette for $geoWithin og $geoIntersects):

$geometry: {
   type: "Polygon",
   coordinates: [ <coordinates> ],
   crs: {
      type: "name",
      properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
   }
}

$polygon

Operatoren $polygon kan bruges til at angive en polygon for en geospatial $geoWithin forespørgsel på ældre koordinatpar. Denne forespørgsel vil derefter returnere de par, der ligger inden for polygonens grænser. $polygon vil dog ikke forespørge efter GeoJSON-objekter. For at definere en polygon skal du angive et array af koordinatpunkter på følgende måde:

{
   : {
      $geoWithin: {
         $polygon: [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
      }
   }
}

Her er det sidste punkt implicit forbundet med det første. Du kan nævne så mange punkter eller sider, som du vil.

Følgende forespørgsel vil f.eks. returnere alle de dokumenter, hvis koordinater findes inden for polygonen defineret af [0,0], [1,5] og [3,3]:

db.places.find(
  {
     loc: {
       $geoWithin: { $polygon: [ [ 0 , 0 ], [ 1 , 5 ], [ 3 , 3 ] ] }
     }
  }
)

$geoWithin

Denne operatør kan bruges til at vælge dokumenter med geodata, som er helt indeholdt i en bestemt form. Den angivne form kan enten være en GeoJSON-multipolygon, en GeoJSON-polygon (enten med flere ringe eller en enkelt ring) eller en form, der kan defineres ved hjælp af ældre koordinatpar.

Operatoren $geoWithin vil udnytte operatoren $geometry til at nævne GeoJSON-objektet.

For at nævne GeoJSON-multipolygoner eller -polygoner via standard koordinatreferencesystemet (CRS) kan du bruge nedenstående syntaks:

{
   : {
      $geoWithin: {
         $geometry: {
            type: <"Polygon" or "MultiPolygon"> ,
            coordinates: [ <coordinates> ]
         }
      }
   }
}

For $geoWithin forespørgsler, der nævner GeoJSON-geometrier med områder, der er større end en enkelt halvkugle, vil brugen af standard CRS føre til forespørgsler om de komplementære geometrier.

Hvis du vil nævne en GeoJSON-polygon med en enkelt ring med et brugerdefineret MongoDB CRS, kan du udnytte nedenstående prototype i $geometry -udtrykket:

{
   : {
      $geoWithin: {
         $geometry: {
           type: "Polygon" ,
           coordinates: [ <coordinates> ],
           crs: {
              type: "name",
              properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
           }
         }
      }
   }
}

Det følgende eksempel vælger alle de lok-data, der findes fuldstændigt inden for en GeoJSON-polygon, idet polygonens areal er mindre end arealet af en enkelt halvkugle:

db.places.find(
   {
     loc: {
       $geoWithin: {
          $geometry: {
             type : "Polygon" ,
             coordinates: [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ]
          }
       }
     }
   }
)

$box

Du kan bruge $box til at angive et rektangel for en geospatial $geoWithin -forespørgsel for at få dokumenter, der ligger inden for rektanglets grænser, i henhold til deres punktbaserede lokaliseringsdata. Når du bruger $geoWithin sammen med $box, får du dokumenter baseret på forespørgselskoordinater. I dette scenario vil $geoWithin ikke forespørge efter GeoJSON-former.

For at udnytte operatoren $box skal du nævne rektanglets øverste højre og nederste venstre hjørne i et arrayobjekt:

{ <location field> : { $geoWithin: { $box: [ [ <bottom left coordinates> ],
 [ <upper right coordinates> ] ] } } }

Ovennævnte forespørgsel vil beregne afstanden ved hjælp af planar (flad) geometri. Følgende forespørgsel returnerer alle de dokumenter, der ligger inden for den kasse, der har punkter på: [0,0], [0,30], [30,0], [30,30]:

db.places.find ( { 
 loc: { $geoWithin: { $box: [ [ 0,0 ], [ 30,30 ] ] } }
} )

$nearSphere

Du kan bruge $nearSphere til at nævne et punkt, for hvilket en geografisk forespørgsel returnerer dokumenterne fra det nærmeste til det fjerneste punkt.

MongoDB bruger sfærisk geometri til at beregne afstandene for $nearSphere. Det vil have brug for et geospatialt indeks som følger:

  1. 2d-indeks for lokaliseringsdata, der er beskrevet som ældre koordinatpar. For at udnytte et 2d-indeks på GeoJSON-punkter skal du generere indekset på GeoJSON-objektets koordinatfelt.
  2. 2dsphere-indeks for lokaliseringsdata, der er beskrevet som GeoJSON-punkter.

For at nævne et GeoJSON-punkt kan du bruge følgende syntaks:

{
  $nearSphere: {
     $geometry: {
        type : "Point",
        coordinates : [ <longitude>, <latitude> ]
     },
     $minDistance: <distance in meters>,
     $maxDistance: <distance in meters> 
  }
}

Her er $minDistance og $maxDistance valgfrie. $minDistance kan begrænse resultaterne til de dokumenter, der er mindst den angivne afstand fra centrum. Du kan bruge $maxDistance til begge indeks.

Overvej nu en samling af “steder”, der består af dokumenter med et stedfelt, der har et 2dsphere-indeks. Følgende eksempel ville returnere de punkter, hvis placering er mindst 2.000 meter og højst 6.000 meter fra det punkt, du vælger, ordnet fra nærmest til fjernest:

db.places.find(
   {
     location: {
        $nearSphere: {
           $geometry: {
              type : "Point",
              coordinates : [ -43.9532, 50.32 ]
           },
           $minDistance: 2000,
           $maxDistance: 6000
        }
     }
   }
)

$geoIntersects

Operatoren $geoIntersects giver dig mulighed for at vælge dokumenter, hvis geospatiale data skærer et bestemt GeoJSON-objekt (dvs. hvor konvergensen mellem det angivne objekt og dataene ikke er tom). Den udnytter operatoren $geometry til at angive GeoJSON-objektet.

For at nævne GeoJSON multipolygoner eller polygoner gennem standard koordinatreferencesystemet (CRS) kan du bruge følgende syntaks:

{ <location field>: {
     $geoIntersects: {
        $geometry: {
           type: "<GeoJSON object type>" ,
           coordinates: [ <coordinates> ]
        }
     }
  }
}

Følgende eksempel bruger $geoIntersects til at vælge alle de lok-data, der skærer polygonen, som beskrives af koordinatarrayet:

db.places.find(
   {
     loc: {
       $geoIntersects: {
          $geometry: {
             type: "Polygon" ,
             coordinates: [
               [ [ 0, 0 ], [ 2, 6 ], [ 4, 1 ], [ 0, 0 ] ]
             ]
          }
       }
     }
   }
)

$center

Operatoren $center nævner en cirkel for en $geoWithin forespørgsel, der returnerer de koordinatpar, der ligger inden for cirklens grænser.

$center returnerer ikke GeoJSON-objekter. For at udnytte operatoren $center skal du angive et array, der indeholder:

  1. Cirklens radius, målt i de enheder, der anvendes af koordinatsystemet.
  2. Gitterkoordinaterne for cirklens midtpunkt.
{
  <location field> : {
      $geoWithin: { $center: [ [ <x> , <y> ] , <radius> ] }
   }
}

I eksemplet nedenfor returneres alle de dokumenter, hvis koordinater kan findes inden for cirklen centreret på [2,3] og med en radius på 40:

db.places.find(
   { loc: { $geoWithin: { $center: [ [2, 3], 40 ] } } }
)

Fremskrivningsoperatorer

Du kan bruge projektionsoperatorer til at nævne de felter, der returneres af en operation. MongoDB-projektionsoperatorer gør det muligt at bruge find() -funktionen med datafiltreringsargumenter. Dette hjælper brugerne med kun at udtrække de nødvendige datafelter fra et dokument. Så det giver dig mulighed for at projicere gennemsigtige og præcise data uden at påvirke den samlede databaseydelse.

$elemMatch (projektion)

Operatoren $elemMatch er ansvarlig for at begrænse indholdet af et felt fra forespørgselsresultaterne til kun at indeholde det første element, der matcher $elemMatch betingelsen.

Her er et par ting, du skal være opmærksom på, før du bruger $elemMatch:

  • Fra MongoDB 4.4 returnerer $elemMatch -projektionen af et eksisterende felt, uanset rækkefølgen af felterne i dokumentet, feltet efter inddragelse af andre eksisterende felter.
  • Både operatorerne $elemMatch og $ viser det første matchende element fra et array baseret på en specificeret betingelse. Operatoren $ projicerer det første matchende array-element fra hvert dokument i en samling på grundlag af en betingelse fra forespørgselsmeddelelsen, hvorimod operatoren $elemMatch projektion tager et eksplicit betingelsesargument. Dette giver dig mulighed for at projicere på grundlag af en betingelse, der ikke findes i forespørgslen, eller hvis du har brug for at projicere på grundlag af forskellige felter i arrayets indlejrede dokumenter.

Du bør også være opmærksom på følgende begrænsninger, før du bruger operatoren $elemMatch på dine data:

  • Du kan ikke nævne et $text forespørgselsudtryk i en $elemMatch operator.
  • db.collection.find() operationer på visninger understøtter ikke $elemMatch projektionsoperatoren.

Det følgende eksempel på $elemMatch projektionsoperatoren forudsætter en samling schools med følgende dokumenter:

{
 _id: 1,
 zipcode: "63108",
 students: [
              { name: "mark", school: 102, age: 9 },
              { name: "geoff", school: 101, age: 13 },
              { name: "frank", school: 104, age: 12 }
           ]
}
{
 _id: 2,
 zipcode: "63110",
 students: [
              { name: "harry", school: 103, age: 14 },
              { name: "george", school: 103, age: 7 },
           ]
}
{
 _id: 3,
 zipcode: "63108",
 students: [
              { name: "harry", school: 103, age: 14 },
              { name: "george", school: 103, age: 7 },
           ]
}
{
 _id: 4,
 zipcode: "63110",
 students: [
              { name: "jim", school: 103, age: 9 },
              { name: "michael", school: 103, age: 12 },
           ]
}

I dette tilfælde søger operationen find() efter alle dokumenter, hvor værdien af postnummerfeltet er 63110. Projektionen $elemMatch ville kun returnere det første matchende element i arrayet students, hvor feltet school har værdien 103:

db.schools.find( { zipcode: "63110" },
                 { students: { $elemMatch: { school: 103 } } } )

Sådan vil resultatet se ud:

{ "_id" : 2, "students" : [ { "name" : "harry", "school" : 103, "age" : 14 } ] }
{ "_id" : 4, "students" : [ { "name" : "jim", "school" : 103, "age" : 9 } ] }

$slice (projektion)

Operatoren $slice projection kan bruges til at angive antallet af elementer i et array, der skal returneres i forespørgselsresultatet:

db.collection.find(
   <query> ,
   { <arrayField> : { $slice: <number> } }
);

Det kan også udtrykkes på denne måde:

db.collection.find(
  <query> ,
   { <arrayField> : { $slice: [ <number> , <number> ] } }
);

For at demonstrere det samme kan du oprette en eksempelsamling af tweets med følgende dokumenter:

db.posts.insertMany([
   {
     _id: 1,
     title: "Nuts are not blueberries.",
     comments: [ { comment: "0. true" }, { comment: "1. blueberries aren't nuts."} ]
   },
   {
     _id: 2,
     title: "Coffee please.",
     comments: [ { comment: "0. Indubitably" }, { comment: "1. Cuppa tea please" }, { comment: "2. frappucino" }, { comment: "3. Mocha latte" }, { comment: "4. whatever" } ]
   }
])

Følgende operation ville bruge $slice projektionsoperatoren på tweets-arrayet til at returnere arrayet med de to første elementer. Hvis et array indeholder mindre end to elementer, returneres alle elementer i arrayet:

db.posts.find( {}, { comments: { $slice: 2 } } )

Denne operation ville returnere følgende dokumenter:

{
   "_id" : 1,
   "title" : "Nuts are not blueberries.",
   "comments" : [ { "comment" : "0. true" }, { "comment" : "1. blueberries aren't nuts." } ]
}
{
   "_id" : 2,
   "title" : "Coffee please.",
   "comments" : [ { "comment" : "0. Indubitably" }, { "comment" : "1. Cuppa tea please" } ]
}

$ (fremskrivning)

Operatoren $ begrænser indholdet af et array til at returnere det første element, der svarer til forespørgselsbetingelsen for arrayet. Du kan bruge $ i projektionsdokumentet i find() -metoden eller findOne() -metoden, når du kun har brug for et bestemt array-element i de valgte dokumenter.

Sådan ser syntaksen for operatoren $ ud:

db.collection.find( { <array>: <condition> ... },
                    { "<array>.$": 1 } )
db.collection.find( { <array.field>: <condition> ...},
                    { "<array>.$": 1 } )

I dette eksempel består students -samlingen af følgende dokumenter:

{ "_id" : 1, "semester" : 2, "grades" : [ 75, 67, 93 ] }
{ "_id" : 2, "semester" : 2, "grades" : [ 60, 68, 72 ] }
{ "_id" : 3, "semester" : 2, "grades" : [ 95, 82, 67 ] }
{ "_id" : 4, "semester" : 3, "grades" : [ 89, 95, 70 ] }
{ "_id" : 5, "semester" : 3, "grades" : [ 68, 98, 82 ] }
{ "_id" : 6, "semester" : 3, "grades" : [ 65, 70, 76 ] }

I den følgende forespørgsel returnerer projektionen { "grades.$": 1 } kun det første element, der er større end eller lig med 89 for feltet grades:

db.students.find( { semester: 2, grades: { $gte: 89 } },
                  { "grades.$": 1 } )

Denne operation returnerer følgende dokumenter:

{"_id": 1, "grades": [93] }

Evaluering Operatorer

Du kan bruge MongoDB-evalueringsoperatorer til at vurdere den overordnede datastruktur eller det enkelte felt i et dokument.

Lad os se på nogle almindelige MongoDB-evalueringsoperatorer.

$mod

Du kan bruge denne operatør til at matche dokumenter, hvor et specificeret felts værdi er lig med resten efter at være blevet divideret med en specificeret værdi:

{ field: { $mod: [ divisor, remainder ] } }

Lad os sige, at du har en tabel med biler, der tilhører forskellige mærker, som du ejer i dit showroom. Følgende forespørgsel ville give dig alle bilmærker, hvis lagernumre er multipla af 250.

db.cars.find ( { qty: { $mod: [ 250,0 ] } } )

$jsonSchema

Med $jsonSchema kan du matche de dokumenter, der passer til det angivne JSON-skema. MongoDB’s implementering af JSON-skemaet omfatter tilføjelsen af nøgleordet bsonType, som lader dig bruge alle BSON-typer inden for operatoren $jsonSchema.

bsonType kan acceptere de samme strengaliaser, som du ville bruge til operatoren type. Sådan ville $jsonSchema‘s syntaks se ud:

{ $jsonSchema: <JSON Schema object> }

Her er JSON-skemaobjektet formateret i henhold til JSON-skema-standardens udkast 4:

{ <keyword1>: <value1>, ... }

Her er et eksempel, der viser, hvordan $jsonSchema fungerer:

{ $jsonSchema: {
     required: [ "name", "major", "gpa", "address" ],
     properties: {
        name: {
           bsonType: "string",
           description: "must be a string and is required"
        },
        address: {
           bsonType: "object",
           required: [ "zipcode" ],
           properties: {
               "street": { bsonType: "string" },
               "zipcode": { bsonType: "string" }
           }
        }
     }
  }
}

Du kan også bruge $jsonSchema i en dokumentvalidator til at håndhæve det angivne skema ved opdaterings- og indsættelsesoperationer:

db.createCollection(<collection> , { validator: { $jsonSchema: <schema> } } )
db.runCommand( { collMod: <collection>, validator:{ $jsonSchema: <schema> } } )

Husk på, at der er flere ting, der ikke understøttes af operatoren $jsonSchema:

  1. Den hele taltype. Du skal udnytte BSON-typen long eller int med nøgleordet bsonType.
  2. Ukendte nøgleord.
  3. Linking properties og hypermedia i JSON-skemaet sammen med brugen af JSON-referencer og JSON-pointere.

$text

Operatoren $text ville søge efter en tekst i indholdet af det angivne felt, indekseret med et tekstindeks:

{  
  $text:  
    {  
      $search: <string>,  
      $language: <string>,  
      $caseSensitive: <boolean>,  
      $diacriticSensitive: <boolean>   
    }  
}

I dette tilfælde vil følgende kodestykke gennemgå tabellen for at filtrere alle biler, der indeholder teksten “Porsche”, fra:

db.cars.find( { $text: { $search: "Porsche" } } )

$regex

Operatoren $regex giver mulighed for at anvende regulære udtryk til at matche mønsterstrenge i forespørgsler. MongoDB anvender regulære udtryk, der er kompatible med Perl:

{<field> : /pattern/ <options>}

Følgende eksempel ville hjælpe med at filtrere alle biler, der indeholder strengen “$78900”, fra:

db.cars.find( { price: { $regex: /$78900/ } } )

$expr

Operatoren $expr giver dig mulighed for at udnytte aggregeringsudtryk i forespørgselssproget:

{ $expr: { <expression> } }

Du kan også bruge $expr til at opbygge forespørgselsudtryk, der sammenligner felter fra det samme dokument i et $match trin. Hvis $match -stadiet tilfældigvis er en del af et $lookup -stadium, kan $expr sammenligne felter ved hjælp af let-variabler.

$where

Du kan udnytte operatoren $where til enten at sende en string, der indeholder en fuld JavaScript-funktion eller et JavaScript-udtryk, til forespørgselssystemet. Operatoren $where giver større fleksibilitet, men kræver, at databasen behandler JavaScript-funktionen eller -udtrykket for hvert dokument i samlingen. Du kan henvise til dette dokument i JavaScript-funktionen eller -udtrykket ved at bruge enten obj eller this.

Her er et eksempel på syntaksen:

{ $where: <string|JavaScript Code> }

Der er nogle få vigtige overvejelser, som du skal huske på, før vi dykker ned i et eksempel, mens du bruger operatoren $where:

  • Du bør kun bruge forespørgselsoperatoren $where til dokumenter på øverste niveau. Operatoren $where query operator vil ikke fungere i et indlejret dokument, som i en $elemMatch query.
  • Generelt bør du kun bruge $where, når du ikke kan udtrykke din forespørgsel via en anden operator. Hvis du er nødt til at bruge $where, skal du sørge for at inkludere mindst én anden standard forespørgselsoperator til at filtrere resultatmængden. Hvis du bruger $where uafhængigt, skal du foretage en samlingsscanning for at kunne udføre den korrekt.

Her er et eksempel til at illustrere dette:

db.cars.find( { $where: function() {  
   return (hex_md5(this.name)== "9a43e617b50cd379dca1bc6e2a8")  
} } );

Bitvise operatorer

Bitvise operatorer returnerer data baseret på bit-positionsbetingelser. Kort sagt bruges de til at matche numeriske eller binære værdier, hvor en bit fra et sæt bit-positioner har værdien 1 eller 0.

$bitsAllSet

Denne operator vil matche alle dokumenter, hvor alle bitpositioner, der er angivet i forespørgslen, er sat (dvs. 1) i feltet:

{ <field> : { $bitsAllSet: <numeric bitmask> } }
{ <field> : { $bitsAllSet: < BinData bitmask> } }
{ <field> : { $bitsAllSet: [ <position1> , <position2> , ... ] } }

Feltværdien skal enten være en BinData-instans eller numerisk for $bitsAllSet for at matche det aktuelle dokument.

I det følgende eksempel udnytter vi en samling med følgende dokumenter:

db.collection.save({ _id: 1, a: 54, binaryValueofA: "00110110" })
db.collection.save({ _id: 2, a: 20, binaryValueofA: "00010100" })
db.collection.save({ _id: 3, a: 20.0, binaryValueofA: "00010100" })
db.collection.save({ _id: 4, a: BinData(0, "Zg=="), binaryValueofA: "01100110" })

Den nedenfor nævnte forespørgsel vil bruge operatoren $bitsAllSet til at teste, om felt a har bits sat på position 1 og position 5, hvor den mindst betydningsfulde bit ville være på position 0:

db.collection.find( { a: { $bitsAllSet: [ 1, 5 ] } })

Denne forespørgsel vil matche følgende dokumenter:

{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" }
{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" }

$bitsAllClear

Operatoren $bitsAllClear vil matche dokumenter, hvor alle de bitpositioner, der er angivet i forespørgslen, er clear eller 0:

{ <field> : { $bitsAllClear: <numeric bitmask> } }
{ <field> : { $bitsAllClear: < BinData bitmask> } }
{ <field> : { $bitsAllClear: [ <position1> , <position2> , ... ] } }

Vi bruger eksemplet for $bitsAllSet her for at demonstrere brugen af $bitsAllClear. Følgende forespørgsel ville bruge denne operator til at kontrollere, om felt a har bitsene clearet på positionerne 1 og 5:

db.collection.find( { a: { $bitsAllClear: [ 1, 5 ] } } )

Denne forespørgsel ville matche følgende dokumenter:

{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" }
{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" }

Meta-operatorer

Der findes forskellige forespørgsels-modifikatorer, som giver dig mulighed for at ændre adfærd eller output af en forespørgsel i MongoDB. Drivergrænsefladerne kan indeholde cursormetoder, der indpakker dem til din brug.

$hint

MongoDB har forældet $hint siden v3.2. Men denne operatør kan stadig være tilgængelig for MongoDB-drivere som Go, Java, Scala, Ruby, Swift osv. Den kan tvinge forespørgselsoptimeringen til at udnytte et specifikt indeks til at opfylde forespørgslen, som derefter kan nævnes enten ved dokument eller ved indeksnavn.

Du kan også bruge operatoren $hint til at teste indekseringsstrategier og forespørgselsydelse. Tag f.eks. følgende operation:

db.users.find().hint( { age: 1 } )

Denne operation ville returnere alle dokumenter i samlingen kaldet users ved at udnytte indekset på feltet age.

Du kan også nævne et hint ved at bruge en af følgende former:

db.users.find()._addSpecial( "$hint", { age : 1 } )
db.users.find( { $query: {}, $hint: { age : 1 } } )

Hvis der findes et indeksfilter for forespørgselsformen, vil MongoDB simpelthen ignorere $hint.

$comment

Operatoren $comment giver dig mulighed for at knytte en kommentar til en forespørgsel i enhver sammenhæng, som $query kan forekomme. Da kommentarer forplanter sig til profilloggen, kan tilføjelse af en kommentar gøre det lettere at fortolke og spore din profil.

Du kan udnytte $comment på en af tre måder:

db.collection.find( { <query> } )._addSpecial( "$comment", <comment> )
db.collection.find( { <query> } ).comment( <comment> )
db.collection.find( { $query: { <query> }, $comment: <comment> } )

Hvis du ønsker at knytte kommentarer til forespørgselsudtryk i andre sammenhænge, f.eks. med db.collection.update(), skal du bruge forespørgselsoperatoren $comment i stedet for metaoperatoren.

$max

Du kan nævne en $max -værdi for at angive den eksklusive øvre grænse for et bestemt indeks for at begrænse resultaterne af find(). Denne operatør angiver den øvre grænse for alle nøgler i en bestemt rækkefølge i indekset.

Mongosh giver dig følgende max() wrapper-metode:

db.collection.find( { <query> } ).max( { field1: <max value> , ... fieldN: <max valueN> } )

Du kan også nævne $max med følgende to former:

db.collection.find( { <query> } )._addSpecial( "$max", { field1: <max value1> ,
 ... fieldN: <max valueN> } )
db.collection.find( { $query: { <query> }, $max: { field1: <max value1> ,
 ... fieldN: <max valueN> } } )

Hvis du f.eks. ønsker at angive den eksklusive øvre grænse, skal du huske følgende operationer på en samling ved navn collection, der indeholder et indeks { age: 1 }:

db.collection.find( { <query> } ).max( { age: 100 } ).hint( { age: 1 } )

Denne operation begrænser forespørgslen til de dokumenter, hvor feltet alder er mindre end 100, og fremtvinger en forespørgselsplan, der scanner { age: 1 } -indekset fra minKey til 100.

$explain

Denne operatør giver dig oplysninger om forespørgselsplanen. Den returnerer et dokument, der beskriver de indekser og processer, der anvendes til at returnere forespørgslen. Dette kan være nyttigt, når du forsøger at optimere en forespørgsel.

Du kan nævne operatoren $explain i en af følgende former:

db.collection.find()._addSpecial( "$explain", 1 )
db.collection.find( { $query: {}, $explain: 1 } )

Bedste praksis for MongoDB-operatorer

I dette afsnit vil vi se på nogle af de bedste fremgangsmåder, når du bruger disse MongoDB-operatører.

Indlejring og henvisninger

Indlejring er en naturlig forlængelse af datamodellering. Det giver dig mulighed for at undgå applikation-joins, hvilket kan reducere opdateringer og forespørgsler.

Du kan indlejre data med et 1:1-forhold i et enkelt dokument. Når det er sagt, kan data med et mange:1-forhold, hvor “mange” objekter vises sammen med deres overordnede dokumenter, også være gode kandidater.

Lagring af disse typer data i samme dokument lyder som et klogt valg. Indlejring giver imidlertid en bedre ydeevne for læseoperationer med denne form for datalokalitet.

Indlejrede datamodeller kan også hjælpe udviklere med at opdatere tilknyttede data i en enkelt skriveoperation. Dette fungerer, fordi skrivninger af enkeltdokumenter er transaktionsbaserede.

Du bør overveje at bruge referencer i følgende scenarier:

  • Når du opdaterer et dokumentsegment, og det bliver længere og længere, mens resten af dokumentet er statisk.
  • Når der er adgang til et dokument, men det indeholder data, der sjældent bruges. Indlejring ville kun øge kravene til hukommelsen, så det giver mere mening at henvise til referencer.
  • Når dokumentstørrelsen går over MongoDB’s dokumentgrænse på 16 MB. Dette kan ske ved modellering af mange:1-relationer (f.eks. medarbejdere:afdeling).

Undersøg profilering og forespørgselsmønstre

For de fleste udviklere er det første skridt i optimering af ydeevnen at forstå de faktiske og forventede forespørgselsmønstre. Når du kender programmets forespørgselsmønstre godt nok, kan du lave din datamodel og vælge et passende indeks.

MongoDB-udviklere har adgang til forskellige kraftfulde værktøjer, der lader dem forbedre ydeevnen. Men det betyder ikke, at forespørgselsprofiler- og mønstre kan ignoreres.

En nem måde at øge ydeevnen på er f.eks. ved at analysere dine forespørgselsmønstre og forstå, hvor du kan indlejre data. Andre måder at forbedre MongoDB-ydelsen på efter at have identificeret dine vigtigste forespørgselsmønstre er bl.a:

  • Sørg for, at du har indeks på alle felter, du forespørger mod.
  • Lagring af resultaterne af hyppige underafspørgsler på dokumenter for at reducere læsebelastningen.
  • Tag et kig på dine logfiler for at se på langsomme forespørgsler, og tjek derefter dine indekser.

Gennemgå dataindeksering og modellering

Mens du laver din datamodel, skal du beslutte, hvordan du skal modellere relationer mellem data. At vælge, hvornår et dokument skal indlejres i stedet for at oprette en reference på tværs af separate dokumenter i forskellige samlinger, er f.eks. et eksempel på applikationsspecifikke overvejelser.

En stor fordel ved JSON-dokumenter er, at de giver udviklere mulighed for at modellere data ud fra applikationens krav. Ved at indlejre underdokumenter og arrays kan du modellere komplekse relationer mellem data ved at udnytte simple tekstdokumenter.

Du kan også bruge MongoDB til at modellere følgende:

  • Geospatiale data
  • Tabulære, flade og kolonneformede strukturer
  • Simple nøgle-værdipar
  • Tidsseriedata
  • Kanter og knuder i forbundne grafdatastrukturer og lignende

Overvåg Sharding og replikering

Replikering kan være afgørende for at forbedre ydeevnen, da det øger datatilgængeligheden gennem horisontal skalering. Replikering kan føre til bedre ydeevne og større sikkerhed gennem redundans.

Overvågning af ydelsen kan være besværlig og kræve ekstra ressourcer og tid for at sikre en problemfri funktion. Du kan udnytte de værktøjer til overvågning af ydeevne, der findes på markedet, og som opfylder dine specifikke behov.

Kinsta APM kan f.eks. indsamle tidsstemplede oplysninger om dit WordPress-websteds MySQL-databaseforespørgsler, PHP-processer, eksterne HTTP-call og meget mere. Du kan også bruge dette gratis værktøj til fejlfinding:

  • Lange API-call
  • Lange eksterne URL-forespørgsler
  • Langsomme databaseforespørgsler for blot at nævne nogle få.

I MongoDB kan replikering opnås gennem replikasæt, der giver udviklere mulighed for at kopiere data fra en primær knude eller server på tværs af flere sekundære knudepunkter. Dette gør det muligt for din replikering at køre nogle forespørgsler på sekundære enheder i modsætning til den primære, hvilket undgår konkurrence og fører til bedre belastningsudligning.

Sharded clusters i MongoDB er en anden måde at forbedre ydeevnen på. I lighed med replikering kan sharding bruges til at fordele store datasæt på flere servere.

Ved at udnytte en shard key kan udviklere kopiere shards eller datastykker på tværs af flere servere. Disse servere kan arbejde sammen om at bruge alle dataene.

Sharding har sin del af fordele, herunder horisontal skalering for skrivning/læsning, højere tilgængelighed og øget lagerkapacitet.

Bestem hukommelsesforbrug

MongoDB fungerer bedst, når et programs arbejdssæt (dvs. data og indekser, der ofte tilgås) passer uden problemer i hukommelsen. Mens andre faktorer er afgørende for ydeevnen, er RAM-størrelsen den vigtigste for instansdimensionering.

Når en applikations arbejdssæt passer i RAM, skal læseaktiviteten fra disken være lav. Men hvis dit arbejdssæt overstiger instansserverens RAM eller størrelse, vil læseaktiviteten begynde at skyde i vejret.

Hvis du ser dette ske, kan du måske løse problemet ved at flytte over til en større instans, der har mere hukommelse.

Placér felter med flere værdier i slutningen

Hvis du indekserer et par felter, og et af de felter, du vil spørge om, bruger en af disse “multi-value”-operatorer, bør du placere dem i slutningen af indekset. Du skal ordne indekset således, at de felter, hvor der spørges efter nøjagtige værdier, kommer først, og at “multi-value”-operatorerne vises sidst i indekset.

En undtagelse herfra er sortering i forhold til felterne. Placer disse mellem “multi-værdi”-felterne og de nøjagtige felter for at reducere den nødvendige sortering i hukommelsen.

Oversigt

For MongoDB er hastighed det vigtigste. For at returnere forespørgsler hurtigt udnytter MongoDB operatorer til at udføre matematiske eller logiske opgaver. Forståelse af MongoDB-operatorer er simpelthen nøglen til at mestre MongoDB.

Denne artikel fremhævede nogle af de vigtigste MongoDB-operatorer, som du kan bruge på dine data, såsom sammenligningsoperatører, logiske operatører, metaoperatorer og projektionsoperatører for blot at nævne nogle få. Den hjælper dig også med at forstå, hvordan du kan bruge MongoDB-operatorer og de bedste fremgangsmåder, der gør det muligt for dig at få det bedste ud af dem.

Blandt alle operatorer, hvilken(n) bruger du oftest og hvorfor? Del det i kommentarerne nedenfor – vi vil gerne høre dine tanker!

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.