1. Översikt
Ibland behöver vi ID:t för ett dokument som vi precis infogat i en MongoDB-databas. Vi kanske till exempel vill skicka tillbaka ID:t som ett svar till en uppringare eller logga det skapade objektet för felsökning.
I den här handledningen kommer vi att se hur ID:n implementeras i MongoDB och hur man hämtar ID:t för ett dokument som vi precis infogat i en samling via ett Java-program.
2. Vad är ID för ett MongoDB-dokument?
Som i alla datalagringssystem behöver MongoDB en unik identifierare för varje dokument som lagras i en samling. Denna identifierare är likvärdig med primärnyckeln i relationsdatabaser.
I MongoDB består detta ID av 12 byte:
- ett 4-byte tidsstämpelvärde representerar sekunderna sedan Unix-epoken
- ett 5-byte slumpmässigt värde som genereras en gång per process. Detta slumpmässiga värde är unikt för maskinen och processen.
- en 3-byte ökande räknare
ID:t lagras i ett fält som heter _id och genereras av klienten. Detta innebär att ID:t måste skapas innan dokumentet skickas till databasen. På klientsidan kan vi antingen använda ett förargenererat ID eller skapa ett anpassat ID.
Vi kan se att dokument skapade av samma klient i samma sekund kommer att ha de första 9 byten gemensamma. Därför är det unika med ID:t beroende av disken i det här fallet. Räknaren låter en klient skapa över 16 miljoner dokument på samma sekund.
Även om det börjar med en tidsstämpel bör vi vara försiktiga så att identifieraren inte används som ett sorteringskriterium. Detta beror på att dokument som skapats i samma sekund inte garanteras sorteras efter skapandedatum, eftersom räknaren inte garanterat är monoton. Dessutom kan olika klienter ha olika systemklockor.
Java-drivrutinen använder en slumptalsgenerator för räknaren, som inte är monoton. Det är därför vi inte bör använda det förargenererade ID:t för att sortera efter skapandedatum.
3. ObjectId Klass
Den unika identifieraren lagras i ett ObjectId klass som tillhandahåller bekväma metoder för att få data lagrade i ID:t utan att tolka det manuellt.
Så här kan vi till exempel få fram datumet för id:t:
Date creationDate = objectId.getDate();
På samma sätt kan vi hämta ID:ts tidsstämpel på några sekunder :
int timestamp = objectId.getTimestamp();
ObjectId klass tillhandahåller också metoder för att få räknaren, maskinidentifieraren eller processidentifieraren, men de är alla utfasade.
4. Hämtar ID:t
Det viktigaste att komma ihåg är att i MongoDB genererar klienten den unika identifieraren för ett Dokument innan du skickar den till klustret. Detta till skillnad från sekvenser i relationsdatabaser. Detta gör det ganska enkelt att hämta detta ID.
4.1. Förargenererat ID
Det vanliga och enkla sättet att generera det unika ID:t för ett Dokument är genom att låta föraren göra jobbet. När vi infogar ett nytt Dokument till en samling , om inget _id fältet finns i Dokumentet , genererar drivrutinen ett nytt ObjectId innan du skickar insert-kommandot till klustret.
Vår kod för att infoga ett nytt Dokument in i din samling kan se ut så här:
Document document = new Document();
document.put("name", "Shubham");
document.put("company", "Baeldung");
collection.insertOne(document);
Vi kan se att vi aldrig anger hur ID:t ska genereras.
När insertOne() metod returnerar, kan vi få det genererade ObjectId från Dokumentet :
ObjectId objectId = document.getObjectId("_id");
Vi kan också hämta ObjectId som ett standardfält i Dokumentet och casta den sedan till ObjectId :
ObjectId oId = (ObjectId) document.get("_id");
4.2. Anpassat ID
Det andra sättet att hämta ID:t är att generera det i vår kod och lägga det i Dokumentet som alla andra områden. Om vi skickar ett Dokument med ett _id fältet till föraren, kommer det inte att generera ett nytt.
Vi kan kräva detta i vissa fall där vi behöver ID:t för MongoDB Dokument innan du infogar Dokumentet i Samlingen .
Vi kan generera ett nytt ObjectId genom att skapa en ny instans av klassen :
ObjectId generatedId = new ObjectId();
Eller så kan vi också anropa den statiska get() metod för ObjectId klass:
ObjectId generatedId = ObjectId.get();
Sedan behöver vi bara skapa vårt Dokument och använd det genererade ID:t. För att göra det kan vi tillhandahålla det i dokumentet konstruktör:
Document document = new Document("_id", generatedId);
Alternativt kan vi använda put() metod:
document.put("_id", generatedId);
När vi använder ett användargenererat ID måste vi vara försiktiga med att generera ett nytt ObjectId före varje infogning, eftersom duplicerade ID är förbjudna. Dubbletter av ID kommer att resultera i en MongoWriteException med ett duplicerat nyckelmeddelande.
ObjectId class tillhandahåller flera andra konstruktorer som tillåter oss att ställa in vissa delar av identifieraren:
public ObjectId(final Date date)
public ObjectId(final Date date, final int counter)
public ObjectId(final int timestamp, final int counter)
public ObjectId(final String hexString)
public ObjectId(final byte[] bytes)
public ObjectId(final ByteBuffer buffer)
Men vi bör vara mycket försiktiga när vi använder dessa konstruktörer eftersom det unika i ID:t som tillhandahålls till föraren är helt beroende av vår kod. Vi kan få dubbletter av nycklar i dessa speciella fall:
- om vi använder samma datum (eller tidsstämpel) &räknarekombination flera gånger
- Om vi använder samma hexadecimala sträng , byte array eller ByteBuffer flera gånger