I alla företag så är data den största tillgången. Genom att analysera data så kan du exempelvis fatta beslut om kundtrender och beteendeförutsägelser. Som ett resultat så ökar företagets lönsamhet och effektivt beslutsfattande.
Utan databasprogramvara så skulle en enkel uppgift som att hitta genomsnittet av alla värden i ett system fullt av poster vara tråkig. Lyckligtvis så har databaser gjort analysen av data enklare och snabbare med hjälp av funktioner och operatörer.
Den här artikeln kommer att kasta lite ljus över de operatörer som används i databasprogramvaran MongoDB.
Vad är MongoDB-operatärer?
MongoDB är en NoSQL-databasprogramvara som hanterar dokumentorienterad information.
En av MongoDB’s viktigaste egenskaper är exempelvis dess snabbhet. För att returnera begäranden snabbare så kan MongoDB exempelvis använda operatörer för att utföra specifika funktioner.
Operatorer är speciella symboler som hjälper kompilatorer att utföra matematiska eller logiska uppgifter. MongoDB erbjuder flera typer av operatörer för att interagera med databasen.
MongoDB’s operatörstyper
Det finns nio typer av operatörer, var och en benämnd efter sin funktion. Logiska operatörer använder exempelvis logiska operationer. För att utföra dem så måste du använda ett specifikt nyckelord och följa syntaxen. De är dock ganska lätta att följa!
I slutet av artikeln så kommer du att känna till grunderna för varje operatör och dess funktioner.
Logiska operatörer
Logiska operatörer används ofta för att filtrera data utifrån givna villkor. Som ett resultat av dessa så blir det även möjligt att utvärdera många villkor, vilket vi kommer att diskutera närmare.
Nedan så följer några logiska operatörer som du kan använda:
$and
Ett ”and”-villkor utför en logisk ”and”-operation på en matris med två eller flera uttryck. Det väljer de dokument där alla villkor i uttrycken är uppfyllda.
Detta är standardsyntaxen för uttrycket $and
:
{ $and: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
Om vi exempelvis vill välja dokument där priset är 10 dollar och kvantiteten är mindre än 15 så kan vi ange följande fråga:
db.inventory.find( { $and: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )
$or
Ett ”or”-villkor utför en logisk ”or”-operation på en matris med två eller flera uttryck. Det väljer de dokument där minst ett av uttrycken är sant.
Detta är standardsyntaxen för uttrycket $or
:
{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }.
Om vi exempelvis vill välja dokument där priset är 10 dollar eller kvantiteten är mindre än 15 så kan vi ange följande fråga:
db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 } ] } )
Vi behöver inte begränsa uttrycket till två kriterier – vi kan lägga till fler. Med nedanstående fråga så väljs exempelvis de dokument där priset är 10 dollar, kvantiteten är mindre än 15 eller taggen är stationär:
db.inventory.find( { $or: [ { quantity: { $lt: 15 } }, { price: 10 }, { tag: "stationary" }] } )
När dessa klausuler körs så utför MongoDB antingen en samlingsskanning eller en indexskanning. Om alla index har stöd för klausulerna så använder MongoDB index för att kontrollera ett $or
-uttryck. I annat fall så används istället en samlingsavläsning.
Men om du vill testa kriterierna i samma fält så bör du kanske använda operatören $in
i stället för $or
. Om du exempelvis vill ha en samling dokument där kvantiteten är antingen 10 eller 20 så kan du behöva köra nedanstående $in
-fråga istället:
db.inventory.find ( { quantity: { $in: [20, 50] } } )
Vi kommer att behandla $in
-operatören närmare senare.
$nor
Den här operatören utför en logisk ”nor”-operation på en matris med hjälp av ett eller flera uttryck. Därefter så väljer den de dokument som inte uppfyller begärande-uttrycken. Förenklat så kan man säga att den gör motsatsen till villkoret $or
.
Detta är den allmänna syntaxen:
{ $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] }
Låt oss betrakta följande fråga:
db.inventory.find( { $nor: [ { price: 3.99 }, { sale: true } ] } )
Denna fråga väljer exempelvis de dokument som inkluderar:
- ett värde i prisfältet som inte är lika med 3,99 dollar och ett försäljningsvärde som inte är lika med sant, eller
- ett värde i prisfältet som inte är lika med 3,99 dollar och ett tomt eller obefintligt försäljningsfält, eller
- inget prisfält och ett försäljningsfält som inte är sant, eller
- varken prisfältet eller försäljningsfältet har fyllts i eller är närvarande.
$not
Operatören utför en logisk ”not”-operation på en matris för det angivna uttrycket. Den väljer sedan de dokument som inte matchar frågeuttrycken. Detta inkluderar de dokument som inte inkluderar fältet.
Detta är den allmänna syntaxen:
{ field: { $not: { <operator-expression> } } }
Ta exempelvis följande fråga:
db.inventory.find( { price: { $not: { $lt: 3.99 } } } )
Denna fråga skulle välja ut de dokument som innehåller:
- ett prisfält vars värde är större än eller lika med 3,99 dollar, och
- ett prisfält som inte är ifyllt eller som inte finns.
Jämförelseoperatorer
Jämförelseoperatorer kan exempelvis användas för att jämföra värden i ett eller flera dokument.
Nedan så finns ett kodprov på en enkel inventariesamling för en stormarknad:
{ _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 kommer framöver att använda det här exemplet medan vi beskriver varje jämförelseoperatör i detalj.
Lika med ($eq)
Den här operatören matchar värden som är lika med det givna värdet:
{ <field>: { $eq: <value> } }
Om vi exempelvis vill hämta ett specifikt dokument från inventariesamlingen som har det exakta kvantitetsvärdet ”20”, så skulle vi ange följande kommando:
db.inventory.find( { qty: { $eq: 20 } } )
Frågan skulle ge följande resultat:
{ _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 än ($gt)
Operatören matchar om värdena är större än det angivna värdet:
{ field: { $gt: value } }
I det här exemplet så hämtar vi de dokument där kvantiteten är större än 15:
db.inventory.find({"qty": { $gt: 15}})
Begärandet skulle ge följande:
{ _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 än ($lt)
Operatören matchar om värdena är mindre än det angivna värdet:
{ field: { $lt: value } }
Vi letar efter de dokument som är mindre än 25:
db.inventory.find({"qty": { $lt: 25}})
Begärandet skulle ge följande resultat:
{ _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 än eller lika med ($gte)
Operatören matchar när värdena är större än eller lika med det angivna värdet:
{ field: { $gte: value } }
I det här exemplet så hämtar vi de dokument där kvantiteten är större än eller lika med 25:
db.inventory.find({"qty": { $gte: 25}})
Denna fråga skulle ge följande:
{ _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 än eller lika med ($lte)
Operatören matchar endast om värdena är mindre än eller lika med det angivna värdet:
{ field: { $lte: value } }
Vi letar efter dokumenten med en kvantitet som är mindre än eller lika med 25.
db.inventory.find({"qty": { $lte: 25}})
Vi kan förvänta oss att denna fråga returnerar följande:
{ _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" ] }
In ($in)
Operatören returnerar de dokument som matchar de angivna värdena:
{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }
Värdet för ett fält är lika med alla värden i den angivna matrisen. Om du exempelvis vill hämta dokumenten med värdena ”30” och ”15” i inventariesamlingen så gör du så här:
db.inventory.find({ "qty": { $in: [30, 15]}})
Utmatningen skulle vara:
{ _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" ] }
Inte i ($nin)
Den här operatören returnerar de dokument som inte matchar de givna värdena. Här är den grundläggande syntaxen för operatören $nin
:
{ field: { $nin: [ <value1>, <value2> ... <valueN> ]
$nin
väljer de dokument där:
- fältvärdet inte finns i den angivna matrisen, eller
- fältet inte finns.
Om fältet innehåller matriser, så kommer det att välja matriser där inget element som anges i värdeavsnittet finns. Vi vill exempelvis välja de dokument där kvantiteten inte är lika med 20 eller 15.
Dessutom så matchar den även dokument som inte har något fält för kvantitet:
db.inventory.find({ "qty": { $nin: [ 20, 15 ]}})
Resultatet skulle bli:
{ _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" ] }
Inte lika ($ne)
Operatören $ne
returnerar de dokument där det angivna värdet inte är lika:
{ $ne: value } }
Vi vill exempelvis välja alla dokument där kvantiteten inte är lika med 20:
db.inventory.find( { qty: { $ne: 20 } } )
Resultatet skulle bli:
{ _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" ] }
I ovanstående utdata så kan vi se att frågan kommer att välja dokument som inte har ett kvantitetsfält.
Operatorer för element
Operatörerna för elementfrågor kan identifiera dokument med hjälp av dokumentets fält. Elementoperatörerna består av $exist
och $type
.
$exists
Den här operatören matchar exempelvis dokument som har ett angivet fält. Operatören har ett boolskt värde som kan vara antingen true
eller false
.
Om det anses vara true
så matchar det de dokument som innehåller det fältet, inklusive dokument där fältvärdet är noll. Om <boolean> är false
, så returnerar frågan endast de dokument som inte innehåller fältet.
Här är standardsyntaxen:
{ field: { $exists: <boolean> } } )
Låt oss ta ett exempel där vi har insamlingsdata för en matris som heter ”bagofmarbles”, där varje bag innehåller kulor av olika färger:
{ 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 }
Låt oss exempelvis säga att vi vill ha en fråga som endast returnerar de bags där det finns röda kulor. Detta innebär att vi måste ange det boolska värdet som true
. Låt oss ta en titt:
db.bagofmarbles.find( { red: { $exists: true } } )
Som ett resultat så blir resultatet dokument som innehåller fältet ”red”, även om värdet var null
. Det skulle dock inte bestå av de dokument där fältet ”red” inte ens existerar:
{ 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 }
Om vi bara vill ha de bags där röda kulor inte ens finns som fält så kan vi ange nedanstående fråga:
db.bagofmarbles.find( { red: { $exists: false} )
Resultatet skulle bestå av de dokument som inte innehåller fältet ”red”:
{ green: 2, blue: 4 }
{ green: 2 }
{ blue: 6 }
$type
Denna operatör matchar dokument enligt den angivna fälttypen. Detta är exempelvis användbart när du har mycket ostrukturerade data eller när datatyperna inte är förutsägbara. Dessa fälttyper är specificerade BSON-typer och kan definieras antingen genom typnummer eller alias.
Detta är den allmänna syntaxen för $type
:
{ field: { $type: <BSON type> } }
Låt oss säga att vi har en adressbok som inkluderar dokumenten nedan:
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"
]
}
]
}
När vi tittar på dokumenten ovan så har postnumret olika datatyper. Detta inkluderar exempelvis långa, dubbla, heltal och strängvärden.
Om vi endast vill ha de dokument som har en viss datatyp som postnummer – låt oss ta sträng i det här fallet – måste vi ange följande fråga i kompilatorn:
db.addressBook.find({
"zipCode": {
$type: "string"
}
})
Detta skulle ge följande dokument:
[
{
"_id": 1,
"address": "2100 Jupiter Spot",
"zipCode": "9036325"
},
{
"_id": 5,
"address": "1044 Venus Lane",
"zipCode": [
"99883637232",
"73488976234"
]
}
]
Det finns dessutom en ”number”-typ som innehåller alla långa, heltal eller dubbla värden som en matris som inkluderar ett element av de angivna typerna:
db.addressBook.find( { "zipCode" : { $type : "number" } } )
Utmatning:
[
{
"_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)
}
]
Om dokumenten har en matrisfältstyp så returnerar operatören $type
de dokument där minst ett matriselement matchar den typ som har överlämnats till operatören.
Array-operatorer
MongoDB består även av matris-operatörer för att söka efter dokument som innehåller matriser.
Det finns tre primära operatörer: $all
, $elemMatch
och $size
. Vi kommer att diskutera var och en av dem i detalj nedan.
$all
Operatören $all
väljer de dokument där ett fältvärde är en matris som innehåller de angivna elementen:
{ : { $all: [ <value1> , <value2> ... ] } }
Låt oss exempelvis säga att vi har en samling dokument för en klädbutik med följande under inventering.
{
_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 vill hämta alla dokument (i det här fallet kläderna) från inventarieförteckningen som är kopplade till taggarna ”trendy” och ”y2k”. I nedanstående fråga så används operatören $all
där värdet av fältet tags är en matris vars element inkluderar ”y2k” och ”trendy”:
db.inventory.find( { tags: { $all: [ "y2k", "trendy" ] } } )
Ovanstående sökning ger följande resultat:
{
_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" }
]
}
I exemplet ovan så ser vi även att operatören $all
helt enkelt utför samma funktion som operationen $and
.
Alternativt så kan vi använda nedanstående fråga som skulle ge ett liknande resultat som ovanstående:
db.inventory.find({
$and: [
{
tags: "y2k"
},
{
tags: "trendy"
}
]
})
$elemMatch
Operatören $elemMatch
matchar dokument som innehåller ett matrisfält med minst ett element som matchar alla angivna frågekriterier:
{ : { $elemMatch: { <query1>, <query2>, ... } } }
Vi kan använda jämförelseoperatörer som $lte
och $gte
. Om vi endast anger ett enda frågevillkor i $elemMatch
, och inte använder operatörerna $not
eller $ne
, så kan vi dock utelämna $elemMatch
eftersom den i huvudsak skulle utföra samma funktion.
Det finns ytterligare några saker att tänka på när man använder den här operatören:
- Du kan inte ange ett
$where
-uttryck i en$elemMatch
-operation. - Du kan inte ange ett
$text
-frågeuttryck i en$elemMatch
-operation.
Vi har exempelvis följande dokument i samlingen av studentresultat:
{ _id: 1, results: [ 92, 89, 98 ] }
{ _id: 2, results: [ 85, 99, 99 ] }
Följande fråga matchar endast de dokument där resultatmatrisen innehåller minst ett element som både är större än eller lika med 90 och mindre än 95:
db.studentresults.find( { results: { $elemMatch: { $gte: 90, $lt: 95 } } })
Vår fråga returnerar följande dokument, eftersom elementet 92 är både större än eller lika med 90 och mindre än 95:
{ "_id" : 1, "results" :[ 92, 89, 98 ] }
$size
Operatören $size
returnerar de dokument där matrisens storlek motsvarar det antal element som anges i argumentet:
{ field: { $size: value } }
Här är ett exempel:
db.collection.find( { field: { $size: 2 } });
Detta skulle mata ut alla dokument i den angivna samlingen där fältet är en matris med 2 element: { field: [ orange, apple] }
och { field: [ blue, red] }
, men inte { field: blue}
eller { field: [ raspberry, lemon, grapefruit ] }
.
Vi kan ange ett specifikt värde som storlek men inte ange intervall av värden som storlek.
Geospatiala operatorer
MongoDB gör det exempelvis möjligt att lagra geospatiala data i form av GeoJSON-typer. GeoJSON är ett öppet standardformat som bygger på JavaScript object notation och som kan representera geografiska egenskaper och stödja icke-spatiala attribut. Det finns två typer av geospatiala operatörer som vi kommer att prata om i den här artikeln: geometrispecifikatorer och frågeselektorer.
$geometri
Den här operatören nämner GeoJSON-geometri för användning med följande geospatiala frågeoperatörer: $geoIntersects
$geoWithin
$nearSphere
$near
$geometry
. Den använder EPSG:4326 som standardkoordinatreferenssystem (CRS).
Om man vill nämna GeoJSON-objekt med standard CRS så kan man använda följande utdrag för $geometry
:
$geometry: {
type: "<GeoJSON object type>",
coordinates: [ <coordinates> ]
}
Vill du nämna en GeoJSON-polygon med en enkelringad GeoJSON-polygon som har ett skräddarsytt MongoDB CRS? Då kan du exempelvis använda följande utdrag (du kan bara använda detta för $geoWithin
och $geoIntersects
):
$geometry: {
type: "Polygon",
coordinates: [ <coordinates> ],
crs: {
type: "name",
properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
}
}
$polygon
Operatören $polygon
kan användas för att ange en polygon för en geospatial $geoWithin
-fråga på äldre koordinatpar. Denna fråga kommer sedan att återge de par som ligger inom polygonens gränser. $polygon
kommer dock inte att söka efter några GeoJSON-objekt. För att definiera en polygon så måste du ange en matris av koordinatpunkter enligt följande:
{
: {
$geoWithin: {
$polygon: [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
}
}
}
Här är den sista punkten implicit kopplad till den första. Du kan nämna så många punkter eller sidor som du vill.
Följande fråga ger exempelvis alla dokument vars koordinater ligger inom den polygon som definieras av [0,0], [1,5] och [3,3]:
db.places.find(
{
loc: {
$geoWithin: { $polygon: [ [ 0 , 0 ], [ 1 , 5 ], [ 3 , 3 ] ] }
}
}
)
$geoWithin
Den här operatören kan användas för att välja dokument med geodata som helt och hållet ingår i en viss form. Den angivna formen kan antingen vara en GeoJSON-multipolygon, en GeoJSON-polygon (antingen flerringad eller enkelringad) eller en form som kan definieras med hjälp av äldre koordinatpar.
Operatören $geoWithin
kommer att utnyttja operatören $geometry
för att nämna GeoJSON-objektet.
För att nämna GeoJSON-multipolyjoner eller polygoner via standardkoordinat-referenssystemet (CRS) så kan du använda syntaxen nedan:
{
: {
$geoWithin: {
$geometry: {
type: <"Polygon" or "MultiPolygon"> ,
coordinates: [ <coordinates> ]
}
}
}
}
För $geoWithin
-begäranden som nämner GeoJSON-geometrier med områden som är större än ett enda halvklot, skulle användningen av standard CRS leda till begäranden om de kompletterande geometrierna.
För att nämna en GeoJSON-polygon med en enkelringad GeoJSON-polygon med ett anpassat MongoDB CRS så kan du använda den prototyp som nämns nedan i $geometry
-uttrycket:
{
: {
$geoWithin: {
$geometry: {
type: "Polygon" ,
coordinates: [ <coordinates> ],
crs: {
type: "name",
properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" }
}
}
}
}
}
Följande exempel plockar alla lokdata som finns inom en GeoJSON-polygon, där polygonens area är mindre än arean av en enda hemisfär:
db.places.find(
{
loc: {
$geoWithin: {
$geometry: {
type : "Polygon" ,
coordinates: [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ]
}
}
}
}
)
$box
Du kan använda $box
för att ange en rektangel för en geospatial $geoWithin
-fråga för att tillhandahålla dokument som ligger inom rektangelns gränser. Allt enligt deras punktbaserade lokaliseringsdata. När du använder $geoWithin
med $box
så får du dokument som baseras på frågekoordinater. I det här scenariot så kommer $geoWithin
inte att fråga efter några GeoJSON-former.
För att utnyttja operatören $box
så måste du nämna rektangelns övre högra och nedre vänstra hörn i ett matrisobjekt:
{ <location field> : { $geoWithin: { $box: [ [ <bottom left coordinates> ],
[ <upper right coordinates> ] ] } } }
Den ovannämnda frågan kommer att beräkna avståndet genom att använda platt geometri. Följande fråga returnerar alla dokument som ligger inom den ruta som har punkter på: [0,0], [0,30], [30,0], [30,30]:
db.places.find ( {
loc: { $geoWithin: { $box: [ [ 0,0 ], [ 30,30 ] ] } }
} )
$nearSphere
Du kan använda $nearSphere
för att nämna en punkt som en geospatial fråga returnerar dokumenten för från närmast till längst bort.
MongoDB använder sfärisk geometri för att beräkna avstånden för $nearSphere
. Det behövs ett geospatialt index enligt följande:
- 2d-index för platsdata som beskrivs som äldre koordinatpar. För att utnyttja ett 2d-index för GeoJSON-punkter så måste du generera indexet för koordinatfältet i GeoJSON-objektet.
- 2dsphere-index för platsdata som beskrivs som GeoJSON-punkter.
Den som vill nämna en GeoJSON-punkt kan använda följande syntax:
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
Här är $minDistance
och $maxDistance
valfria. $minDistance
kan begränsa resultaten till de dokument som ligger närmast det angivna avståndet från centrum. Du kan använda $maxDistance
för båda indexen.
Tänk nu på en samling ”platser” som består av dokument med ett fält för plats som har ett 2dsphere-index. Följande exempel skulle ge de punkter vars läge ligger minst 2 000 meter och högst 6 000 meter från den punkt som du väljer, ordnade från närmast till längst bort:
db.places.find(
{
location: {
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ -43.9532, 50.32 ]
},
$minDistance: 2000,
$maxDistance: 6000
}
}
}
)
$geoIntersects
Med operatören $geoIntersects
så kan du välja dokument vars geodata skär ett visst GeoJSON-objekt (dvs. där konvergensen mellan det angivna objektet och datan inte är tom). Operatören $geometry
används för att specificera GeoJSON-objektet.
Om man vill nämna GeoJSON multipolygoner eller polygoner genom standardkoordinat-referenssystemet (CRS) så kan man använda följande syntax:
{ <location field>: {
$geoIntersects: {
$geometry: {
type: "<GeoJSON object type>" ,
coordinates: [ <coordinates> ]
}
}
}
}
Följande instans använder $geoIntersects
för att välja ut alla lokdata som skär polygonen som beskrivs av koordinatmatrisen:
db.places.find(
{
loc: {
$geoIntersects: {
$geometry: {
type: "Polygon" ,
coordinates: [
[ [ 0, 0 ], [ 2, 6 ], [ 4, 1 ], [ 0, 0 ] ]
]
}
}
}
}
)
$center
Operatören $center
nämner en cirkel för en $geoWithin
-fråga som returnerar de koordinatpar som ligger inom cirkelns gränser.
$center
returnerar inte GeoJSON-objekt. För att utnyttja operatören $center
så måste du ange en matris som innehåller:
- Cirkelns radie, mätt i de enheter som används i koordinatsystemet.
- Rutnätskoordinaterna för cirkelns mittpunkt.
{
<location field> : {
$geoWithin: { $center: [ [ <x> , <y> ] , <radius> ] }
}
}
Exemplet nedan returnerar alla dokument som har koordinater som kan hittas inom cirkeln med centrum på [2,3] och med en radie på 40:
db.places.find(
{ loc: { $geoWithin: { $center: [ [2, 3], 40 ] } } }
)
Projektionsoperatorer
Du kan använda projektionsoperatorer för att nämna de fält som returneras av en operation. MongoDB’s projektionsoperatörer gör det möjligt att använda funktionen find()
med argument för datafiltrering. Detta hjälper användarna att extrahera endast de datafält som krävs från ett dokument. Som ett resultat så går det alltså att projicera transparenta och koncisa data utan att påverka den totala databasprestandan.
$elemMatch (projektion)
Operatören $elemMatch
ansvarar för att begränsa innehållet i ett fält från sökresultatet så att det endast innehåller det första elementet som matchar villkoret $elemMatch
.
Här är några saker som du måste tänka på innan du använder $elemMatch
:
- Från och med MongoDB 4.4 så returnerar
$elemMatch
-projektionen av ett befintligt fält, oavsett ordning på fälten i dokumentet, fältet efter andra befintliga fält. - Både operatörerna
$elemMatch
och$
visar det första matchande elementet från en matris baserat på ett angivet villkor. Operatören$
skulle projicera det första matchande elementet i matrisen från varje dokument i en samling baserat på ett visst villkor från frågeformuleringen. Operatören$elemMatch
-projektionen tar istället ett uttryckligt argument för villkoret. På så sätt kan du projicera utifrån ett villkor som inte finns i frågan, eller projicera utifrån olika fält i matrisens inbäddade dokument.
Du bör även vara medveten om följande begränsningar innan du använder $elemMatch
-operatören på dina data:
- Du kan inte nämna ett
$text
-frågeuttryck i en$elemMatch
-operator. db.collection.find()
-operationer på vyer har inte stöd för$elemMatch
-projektionsoperatören.
.
Följande exempel på $elemMatch
-projektionsoperatören utgår från en samling schools
med följande dokument:
{
_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 det här fallet så söker find()
-operationen efter alla dokument där värdet i fältet postnummer är 63110. Projiceringen $elemMatch
skulle endast återge det första matchande elementet i matrisen students
där fältet school
har värdet 103:
db.schools.find( { zipcode: "63110" },
{ students: { $elemMatch: { school: 103 } } } )
Så här skulle resultatet se ut:
{ "_id" : 2, "students" : [ { "name" : "harry", "school" : 103, "age" : 14 } ] }
{ "_id" : 4, "students" : [ { "name" : "jim", "school" : 103, "age" : 9 } ] }
$slice (projektion)
Operatören $slice
-projektion kan användas för att ange hur många element i en matris som ska återges i sökresultatet:
db.collection.find(
<query> ,
{ <arrayField> : { $slice: <number> } }
);
Den kan även uttryckas på följande sätt:
db.collection.find(
<query> ,
{ <arrayField> : { $slice: [ <number> , <number> ] } }
);
För att demonstrera samma sak så kan du skapa en exempelsamling av tweets med följande dokument:
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öljande operation skulle använda $slice
-projektionsoperatören på matrisen tweets för att återge matrisen med de två första elementen. Om en matris innehåller mindre än två element så returneras alla element i matrisen:
db.posts.find( {}, { comments: { $slice: 2 } } )
Denna operation skulle ge följande dokument:
{
"_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" } ]
}
$ (projektion)
Operatören $
begränsar innehållet i en matris så att det första elementet som matchar matrisens frågevillkor returneras. Du kan använda $
i projektionsdokumentet för find()
-metoden eller findOne()
-metoden när du endast behöver ett visst matriselement i valda dokument.
Så här ser syntaxen för operatören $
ut:
db.collection.find( { <array>: <condition> ... },
{ "<array>.$": 1 } )
db.collection.find( { <array.field>: <condition> ...},
{ "<array>.$": 1 } )
I det här exemplet så består samlingen students
av följande dokument:
{ "_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 följande fråga så returnerar projektionen { "grades.$": 1 }
endast det första elementet som är större än eller lika med 89 för fältet grades
:
db.students.find( { semester: 2, grades: { $gte: 89 } },
{ "grades.$": 1 } )
Denna operation returnerar följande dokument:
{"_id": 1, "grades": [93] }
Utvärderingsoperatorer
Du kan använda MongoDB’s utvärderingsoperatörer för att bedöma den övergripande datastrukturen eller enskilda fält i ett dokument.
Låt oss titta på några vanliga MongoDB-utvärderingsoperatörer.
$mod
Du kan använda den här operatören för att matcha dokument där ett specificerat fälts värde är lika med återstoden efter att ha dividerats med ett specificerat värde:
{ field: { $mod: [ divisor, remainder ] } }
Låt oss säga att du har en tabell med bilar av olika märken som du äger i ditt utställningsrum. Följande fråga skulle ge dig alla bilmärken vars lagernummer innehåller 250.
db.cars.find ( { qty: { $mod: [ 250,0 ] } } )
$jsonSchema
Med $jsonSchema
så kan du matcha de dokument som matchar det angivna JSON-schemat. MongoDB’s implementering av JSON-schemat inkluderar tillägget av nyckelordet bsonType
, som låter dig använda alla BSON-typer inom $jsonSchema
-operatören.
bsonType
kan acceptera samma strängalias som du använder för operatören type
. Så här skulle syntaxen för $jsonSchema
se ut:
{ $jsonSchema: <JSON Schema object> }
Här är JSON-objektet formaterat enligt JSON-standardens utkast 4:
{ <keyword1>: <value1>, ... }
Här är ett exempel som visar hur $jsonSchema
fungerar:
{ $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 även använda $jsonSchema
i en dokumentvalidering för att tvinga fram det angivna schemat vid uppdatering och insättning:
db.createCollection(<collection> , { validator: { $jsonSchema: <schema> } } )
db.runCommand( { collMod: <collection>, validator:{ $jsonSchema: <schema> } } )
Tänk på att det finns flera saker som inte stöds av operatören $jsonSchema
:
- Helhetstypen. Du måste använda BSON-typen long eller int med nyckelordet bsonType.
- Okända nyckelord.
- Länkning av egenskaper och JSON-schemats hypermedia, tillsammans med användningen av JSON-referenser och JSON-pointers.
text
Operatören $text
skulle leta efter en text i innehållet i det angivna fältet, indexerat med ett textindex:
{
$text:
{
$search: <string>,
$language: <string>,
$caseSensitive: <boolean>,
$diacriticSensitive: <boolean>
}
}
I det här fallet så kommer följande kodutdrag att gå igenom tabellen för att filtrera bort alla bilar som innehåller texten ”Porsche”:
db.cars.find( { $text: { $search: "Porsche" } } )
$regex
Operatören $regex
erbjuder reguljära uttryck för att matcha strängar i sökfrågor. MongoDB utnyttjar reguljära uttryck som är kompatibla med Perl:
{<field> : /pattern/ <options>}
Följande exempel skulle hjälpa till att filtrera bort alla bilar som innehåller strängen ”$78900”:
db.cars.find( { price: { $regex: /$78900/ } } )
$expr
Operatören $expr
gör det möjligt att utnyttja aggregeringsuttryck i frågespråket:
{ $expr: { <expression> } }
Du kan även använda $expr
för att bygga frågeuttryck som jämför fält från samma dokument i ett $match
-steg. Om $match
-stadiet råkar vara en del av ett $lookup
-stadium så kan $expr
jämföra fält med hjälp av let-variabler.
$where
Du kan utnyttja operatören $where
för att antingen skicka en sträng som innehåller en fullständig JavaScript-funktion eller ett JavaScript-uttryck till frågesystemet. Operatören $where
ger större flexibilitet men kräver att databasen behandlar JavaScript-funktionen eller uttrycket för varje dokument i samlingen. Du kan hänvisa till det här dokumentet i JavaScript-funktionen eller -uttrycket genom att antingen använda obj
eller this
.
Här är ett exempel på syntaxen:
{ $where: <string|JavaScript Code> }
Det finns några viktiga överväganden att tänka på innan vi går in på ett exempel när vi använder $where
-operatören:
- Du bör endast använda
$where
-operatören för att söka efter dokument på högsta nivå. Operatören$where
fungerar inte i ett nästlat dokument, som i en$elemMatch
-fråga. - Generellt sett så bör du endast använda
$where
när du inte kan uttrycka din fråga med en annan operatör. Om du måste använda$where
, se till att du inkluderar minst en annan standardfrågeoperator för att filtrera resultatmängden. Om du använder$where
oberoende av varandra så krävs det en samlingsskanning för att den ska kunna utföras korrekt.
.
Här är ett exempel för att illustrera detta:
db.cars.find( { $where: function() {
return (hex_md5(this.name)== "9a43e617b50cd379dca1bc6e2a8")
} } );
Bitvisa operatorer
Bitvisa operatörer returnerar data baserat på villkor för bitpositioner. Enkelt uttryckt så används de för att matcha numeriska eller binära värden där någon bit från en uppsättning bitpositioner har värdet 1 eller 0.
$bitsAllSet
Denna operatör matchar alla dokument där alla bitpositioner som anges i frågan är inställda (dvs. 1) i fältet:
{ <field> : { $bitsAllSet: <numeric bitmask> } }
{ <field> : { $bitsAllSet: < BinData bitmask> } }
{ <field> : { $bitsAllSet: [ <position1> , <position2> , ... ] } }
Fältvärdet ska antingen vara en BinData-instans eller numeriskt för att $bitsAllSet
ska matcha det aktuella dokumentet.
I följande exempel så utnyttjar vi en samling med följande dokument:
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" })
I den fråga som nämns nedan så används operatören $bitsAllSet
för att testa om fält a har bitar som är inställda på position 1 och position 5. Den minst signifikanta biten skulle vara på position 0:
db.collection.find( { a: { $bitsAllSet: [ 1, 5 ] } })
Denna fråga skulle matcha följande dokument:
{ "_id" : 1, "a" : 54, "binaryValueofA" : "00110110" }
{ "_id" : 4, "a" : BinData(0,"Zg=="), "binaryValueofA" : "01100110" }
$bitsAllClear
Operatören $bitsAllClear
kommer att matcha dokument där alla bitpositioner som anges i frågan är klara eller 0
:
{ <field> : { $bitsAllClear: <numeric bitmask> } }
{ <field> : { $bitsAllClear: < BinData bitmask> } }
{ <field> : { $bitsAllClear: [ <position1> , <position2> , ... ] } }
Vi använder exemplet för $bitsAllSet
här för att visa hur $bitsAllClear
används. Följande fråga skulle använda denna operatör för att kontrollera om fält a har bitar som är klara i positionerna 1 och 5:
db.collection.find( { a: { $bitsAllClear: [ 1, 5 ] } } )
Denna fråga skulle matcha följande dokument:
{ "_id" : 2, "a" : 20, "binaryValueofA" : "00010100" }
{ "_id" : 3, "a" : 20, "binaryValueofA" : "00010100" }
Meta-operatorer
Det finns olika frågemodifierare som gör att du kan ändra beteendet eller resultatet av en fråga i MongoDB. Drivrutinens gränssnitt kan exempelvis tillhandahålla markörmetoder som omsluter dem för din användning.
$hint
MongoDB har avskrivit $hint
sedan v3.2. Men den här operatören kan fortfarande finnas tillgänglig för MongoDB-drivrutiner som Go, Java, Scala, Ruby, Swift osv. Den kan tvinga sökoptimeraren att utnyttja ett specifikt index för att uppfylla sökningen, som sedan kan nämnas antingen med dokument eller med indexnamn.
Du kan även använda operatören $hint
för att testa indexeringsstrategier och frågeprestanda. Ta exempelvis följande operation:
db.users.find().hint( { age: 1 } )
Den här operationen skulle returnera alla dokument i samlingen som kallas users
genom att utnyttja indexet för fältet age
.
Du kan även nämna en ledtråd genom att använda någon av följande former:
db.users.find()._addSpecial( "$hint", { age : 1 } )
db.users.find( { $query: {}, $hint: { age : 1 } } )
Om det finns ett indexfilter för frågeformen så skulle MongoDB helt enkelt ignorera $hint
.
$comment
Med operatören $comment
så kan du bifoga en kommentar till en fråga i alla sammanhang som $query
kan förekomma i. Eftersom kommentarer sprids till profilloggen så kan det bli lättare att tolka och spåra din profil om du lägger till en kommentar.
Du kan använda $comment
på tre olika sätt:
db.collection.find( { <query> } )._addSpecial( "$comment", <comment> )
db.collection.find( { <query> } ).comment( <comment> )
db.collection.find( { $query: { <query> }, $comment: <comment> } )
Om du vill bifoga kommentarer till frågeuttryck i andra sammanhang, exempelvis med db.collection.update()
, så kan du använda frågeoperatören $comment
i stället för metaoperatorn.
$max
Du kan nämna ett $max
-värde för att ange den exklusiva övre gränsen för ett visst index för att begränsa resultaten av find()
. Den här operatören anger den övre gränsen för alla nycklar i en viss ordning i indexet.
Mongosh ger dig följande max()
-omslagsmetod:
db.collection.find( { <query> } ).max( { field1: <max value> , ... fieldN: <max valueN> } )
Du kan även nämna $max
med följande två 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> } } )
Om du exempelvis vill specificera den exklusiva övre gränsen så kan du tänka på följande operationer på en samling som heter collection och som innehåller ett index { age: 1 }
:
db.collection.find( { <query> } ).max( { age: 100 } ).hint( { age: 1 } )
Denna operation begränsar sökningen till de dokument där fältet ålder är mindre än 100 och tvingar fram en sökplan som skannar indexet { age: 1 }
från minKey
till 100.
$explain
Denna operatör ger dig information om frågeplanen. Den returnerar ett dokument som beskriver de index och processer som används för att returnera frågan. Detta kan vara användbart när du försöker att optimera en fråga.
Du kan nämna operatören $explain
i någon av följande former:
db.collection.find()._addSpecial( "$explain", 1 )
db.collection.find( { $query: {}, $explain: 1 } )
Bästa praxis för MongoDB-operatorer
I det här avsnittet så tar vi en titt på några av de bästa metoderna när du använder dessa MongoDB-operatörer.
Inbäddning och hänvisning
Inbäddning är en naturlig förlängning av datamodellering. Det gör att du kan undvika applikations-förbindelser. Som ett resultat så kan uppdateringar och sökningar minskas.
Du kan bädda in data med en 1:1-relation i ett enda dokument. Med detta sagt så kan data med många :1-relationer där ”många” objekt visas med sina överordnade dokument också vara bra kandidater.
Att lagra dessa typer av data i samma dokument låter som ett klokt val. Inbäddning ger dock bättre prestanda för läsoperationer med denna typ av datalokalisering.
Inbäddade datamodeller kan även hjälpa utvecklare att uppdatera associerade data i en enda skrivoperation. Detta fungerar eftersom skrivningar i enskilda dokument är transaktionsbaserade.
Du bör överväga att använda referenstagning för följande scenarier:
- När du uppdaterar ett dokumentsegment och det fortsätter att bli längre, medan resten av dokumentet är statiskt.
- När ett dokument nås men innehåller data som sällan används. Inbäddning skulle bara öka kraven på minnet, så referensering är mer meningsfullt.
- När dokumentstorleken överskrider MongoDB’s dokumentgräns på 16 MB. Detta kan hända när man modellerar många :1-relationer (till exempel anställda:avdelning).
Undersök profilering och frågemönster
För de flesta utvecklare så är det första steget för att optimera prestandan att förstå de faktiska och förväntade frågemönstren. När du väl känner till applikationens frågemönster tillräckligt väl så kan du göra din datamodell och välja lämpliga index.
MongoDB-utvecklare har tillgång till olika kraftfulla verktyg som låter dem förbättra prestandan. Detta betyder dock inte att frågeprofiler och mönster kan ignoreras.
Ett enkelt sätt att öka prestandan är exempelvis att analysera dina frågemönster och förstå var du kan bädda in data. Andra sätt att förbättra MongoDB’s prestanda efter att ha identifierat dina viktigaste frågemönster är bland annat:
- Se till att du har index för alla fält som du frågar mot.
- Lagra resultaten av frekventa underfrågor på dokument för att minska läslasten.
- Ta en titt på dina loggar för att leta efter långsamma begäranden och kontrollera sedan dina index.
Granska indexering och modellering av data
När du gör din datamodell så kommer du att bestämma hur du ska modellera relationer mellan data. Att välja när du ska bädda in ett dokument i stället för att skapa en referens över separata dokument i olika samlingar är exempelvis ett exempel på tillämpningsspecifika överväganden.
En stor fördel med JSON-dokument är att de låter utvecklare modellera data utifrån applikationens krav. Att bädda in underdokument och matriser hjälper dig att modellera komplexa relationer mellan data genom att utnyttja enkla textdokument.
Du kan även använda MongoDB för att modellera följande:
- Geospatiala data
- Tabeller, platta strukturer och kolumnstrukturer
- Enkla nyckel-värdepar
- Tidsseriedata
- Kanter och noder i anslutna grafiska datastrukturer och liknande
Övervaka delning och replikering
Replikering kan vara avgörande för att förbättra prestandan eftersom den ökar tillgängligheten till data genom horisontell skalning. Som ett resultat av detta så kan du få bättre prestanda och ökad säkerhet genom redundans.
Prestandaövervakning kan vara besvärlig och kräva extra resurser och tid för att säkerställa en smidig funktion. Du kan utnyttja de verktyg för prestandaövervakning som finns på marknaden och som tillgodoser dina specifika behov.
Kinsta APM kan exempelvis samla in tidsstämplad information om MySQL-databasfrågor, PHP-processer, externa HTTP-anrop och mycket annat på din WordPress-webbplats. Du kan även använda det här kostnadsfria verktyget för att felsöka:
- Långa API-anrop
- Långa externa webbadress-förfrågningar
- Långsamma databasfrågor för att nämna några.
I MongoDB så kan replikering åstadkommas med hjälp av replikauppsättningar. Som ett resultat av dessa så kan utvecklare kopiera data från en primär nod eller server till flera sekundära noder eller servrar. Detta gör att replikeringen kan köra vissa frågor på sekundära enheter i stället för på den primära. Då kan exempelvis konflikter undvikas och det kan bli en bättre belastningsutjämning.
Sharded-kluster i MongoDB är ett annat sätt att potentiellt förbättra prestandan. I likhet med replikering så kan sharding exempelvis användas för att fördela stora datamängder på flera servrar.
Genom att utnyttja en shardnyckel så kan utvecklare kopiera shards eller datamängder över flera servrar. Som ett resultat så kan servrarna arbeta tillsammans för att använda alla data.
Sharding har en hel del fördelar, bland annat horisontell skalning för skrivningar/läsningar, högre tillgänglighet och ökad lagringskapacitet.
Bestämma minnesanvändning
MongoDB presterar bäst när en applikations arbetsuppsättning (dvs. ofta åtkomna data och index) får plats i minnet utan problem. Även om andra faktorer är avgörande för prestandan så är RAM-storleken den viktigaste för instansstorleken.
När en applikations arbetsmängd exempelvis ryms i RAM så måste läsaktiviteten från disken vara låg. Men om arbetsuppsättningen överskrider instansserverns RAM eller storlek så blir det problem. Som ett resultat så kommer läsaktiviteten att börja skjuta i höjden.
Om du ser detta hända så kan du kanske lösa problemet genom att flytta över till en större instans som har mer minne.
Placera fält med flera värden i slutet
Om du exempelvis indexerar ett par fält och ett av de fält som du vill söka efter använder en av dessa ”multi-value”-operatörer, så bör du placera dem i slutet av indexet. Du måste ordna indexet så att de fält som frågar efter exakta värden kommer först och att operatörerna med flera värden visas sist i indexet.
Ett undantag från detta skulle vara att sortera mot fälten. Placera dessa mellan ”flervärdes”- och exakta fält för att minska den mängd sortering i minnet som krävs.
Sammanfattning
För MongoDB så är snabbhet det viktigaste. MongoDB använder operatörer för att utföra matematiska eller logiska uppgifter. Som ett resultat så returneras frågor väldigt snabbt. Förståelsen av MongoDB’s operatörer är helt enkelt nyckeln till att behärska MongoDB.
Den här artikeln belyser några av de viktigaste MongoDB-operatörerna som du kan använda på dina data. Detta gäller exempelvis jämförelseoperatörer, logiska operatörer, metaoperatörer och projektionsoperatörer, för att nämna några. Den hjälper dig även att förstå hur du kan använda MongoDB-operatorer och de bästa metoderna som gör att du kan få ut så mycket som möjligt av dem.
Bland alla operatörerna, vilken eller vilka använder du oftast och varför? Dela med dig i kommentarerna nedan – vi vill gärna höra dina tankar!
Lämna ett svar