Programmering

MongoDB primære nøgler er din ven

Alle dokumenter i en MongoDB-samling har en primær nøgle kaldet _id. Dette felt tildeles automatisk til et dokument ved indsættelse, så der er sjældent behov for at give det. Hvad der er interessant ved _id felt er, at det er tidsbaseret. Det vil sige den underliggende type _id, som er ObjectId, er en 12-byte BSON-type, og 4 af disse byte repræsenterer sekunderne siden Unix-epoken.

Hvad der også er specielt ved _id felt er, at det automatisk indekseres, som du kan se nedenfor ved at ringe getIndexes på enhver samling.

1 2 3 4 5 6 7 8 9 10 11 
> db.things.getIndexes () [{"v": 1, "key": {"_id": 1}, "ns": "test.things", "name": "_id_"}] 

Og som alle husker fra traditionelle RDBMS'er, er indekser vigtige, fordi de kan gøre dokumenthentning hurtigere; ikke desto mindre forbruger indekser hukommelse, og der er en lille ydeevne, når der indsættes dokumenter, da alle tilsvarende indekser skal opdateres. Så selvom du seriøst bør overveje at bruge indekser, skal du være økonomisk i deres brug.

Naturligvis søger efter et dokument _id er kun praktisk, når du ved godt det. Oftere end ikke søges i dokumenter via andre felter, og hvis du finder dig selv i at søge via en tidsserie, f.eks oprettet_på så er du i en godbid.

Forestil dig en opkaldt samling logfiler der indeholder enkle dokumenter, der fanger forskellige logbeskeder. Et eksempeldokument kunne se sådan ud:

1 2 3 4 5 6 
{"_id": ObjectId ("51c4ab6d4d6906d494460728"), "message": "styrtede ned, ingen sådan metodeundtagelse", "type": "crash", "created_at": ISODate ("2013-06-21T19: 37: 17.992Z ")} 

Hvad hvis jeg ville finde alle logbeskeder til en dato, som i dag? Jeg kunne skrive min forespørgsel sådan:

1 
db.logs.find ({created_at: {'$ gt': new Date (2013, 5, 20)}}) 

Hvis jeg kaster en forklaring til den forespørgsel, kan jeg se det, fordi jeg ikke har et indeks på oprettet_på, en grundlæggende markør er gearet, og alle dokumenter i samlingen blev scannet for at hente mit resultat.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
> db.logs.find ({created_at: {'$ gt': new Date (2013, 5, 20)}}). forklar () {"cursor": "BasicCursor", "isMultiKey": false, "n" : 2, "nscannedObjects": 4, "nscanned": 4, "nscannedObjectsAllPlans": 4, "nscannedAllPlans": 4, "scanAndOrder": false, "indexOnly": false, "nYields": 0, "nChunkSkips": 0 , "millis": 0, "indexBounds": {}, "server": "ghome-computer.home: 27017"} 

Som du kan se, søger via oprettet_på felt kan være ineffektivt; således kan du blive fristet til at kaste et indeks på dette felt. Dette ville naturligvis gøre den pågældende forespørgsel mere effektiv, men du vil pådrage dig omkostningerne ved et nyt indeks, der forbruges mere hukommelse, og indsatser vil være lidt langsommere på grund af en opdatering til det nyoprettede indeks.

Som det viser sig, fordi _id felt integrerer Unix-epoke i den, kan du lige så let lave et find-udtryk uden inklusive oprettet_på Mark. For eksempel giver MongoDB Ruby-driveren dig mulighed for at oprette ObjectIdEr fra en Tid ligesom: