1. Přehled
Někdy potřebujeme ID dokumentu, který jsme právě vložili do databáze MongoDB. Můžeme například chtít poslat zpět ID jako odpověď volajícímu nebo zaprotokolovat vytvořený objekt pro ladění.
V tomto tutoriálu uvidíme, jak jsou ID implementována v MongoDB a jak získat ID dokumentu, který jsme právě vložili do kolekce pomocí programu Java.
2. Jaké je ID dokumentu MongoDB?
Jako v každém systému ukládání dat potřebuje MongoDB jedinečný identifikátor pro každý dokument uložený v kolekci. Tento identifikátor je ekvivalentní primárnímu klíči v relačních databázích.
V MongoDB se toto ID skládá z 12 bajtů:
- 4bajtová hodnota časového razítka představuje sekundy od epochy Unix
- 5bajtová náhodná hodnota generovaná jednou za proces. Tato náhodná hodnota je jedinečná pro stroj a proces.
- 3bajtový přírůstkový čítač
ID je uloženo v poli s názvem _id a je generován klientem. To znamená, že ID musí být vygenerováno před odesláním dokumentu do databáze. Na straně klienta můžeme buď použít ID vygenerované ovladačem, nebo vygenerovat vlastní ID.
Vidíme, že dokumenty vytvořené stejným klientem ve stejnou sekundu budou mít společných prvních 9 bajtů. Jedinečnost ID tedy v tomto případě závisí na počítadle. Čítač umožňuje klientovi vytvořit více než 16 milionů dokumentů za stejnou sekundu.
I když to začíná časovým razítkem, měli bychom si dát pozor, aby identifikátor nebyl použit jako kritérium řazení. Je to proto, že u dokumentů vytvořených ve stejnou sekundu není zaručeno, že budou seřazeny podle data vytvoření, protože není zaručeno, že počítadlo bude monotónní. Různí klienti také mohou mít různé systémové hodiny.
Ovladač Java používá pro počítadlo generátor náhodných čísel, který není monotónní. To je důvod, proč bychom neměli používat ID vygenerované ovladačem pro řazení podle data vytvoření.
3. ObjectId Třída
Jedinečný identifikátor je uložen v ObjectId třída, která poskytuje pohodlné metody pro získání dat uložených v ID bez ruční analýzy.
Zde je například uvedeno, jak můžeme získat datum vytvoření ID:
Date creationDate = objectId.getDate();
Podobně můžeme získat časové razítko ID v sekundách:
int timestamp = objectId.getTimestamp();
ObjectId class také poskytuje metody pro získání počítadla, identifikátoru počítače nebo identifikátoru procesu, ale všechny jsou zastaralé.
4. Načítání ID
Hlavní věc, kterou je třeba si zapamatovat, je, že v MongoDB klient generuje jedinečný identifikátor dokumentu před odesláním do clusteru. To je na rozdíl od sekvencí v relačních databázích. Díky tomu je získání tohoto ID docela snadné.
4.1. ID generované ovladačem
Standardní a snadný způsob generování jedinečného ID dokumentu spočívá v tom, že necháte práci řidiče. Když vložíme nový Dokument do Sbírky , pokud žádné _id pole existuje v Dokumentu , ovladač vygeneruje nové ObjectId před odesláním příkazu insert do clusteru.
Náš kód pro vložení nového dokumentu do vaší sbírky může vypadat takto:
Document document = new Document();
document.put("name", "Shubham");
document.put("company", "Baeldung");
collection.insertOne(document);
Vidíme, že nikdy neuvádíme, jak musí být ID generováno.
Když insertOne() metoda vrátí, můžeme získat vygenerované ObjectId z dokumentu :
ObjectId objectId = document.getObjectId("_id");
Můžeme také získat ObjectId jako standardní pole Dokumentu a poté jej přenést do ObjectId :
ObjectId oId = (ObjectId) document.get("_id");
4.2. Vlastní ID
Dalším způsobem, jak získat ID, je vygenerovat jej v našem kódu a vložit jej do dokumentu jako každý jiný obor. Pokud odešleme Dokument s _id pole do ovladače, nevygeneruje nové.
Můžeme to vyžadovat v některých případech, kdy potřebujeme ID dokumentu MongoDB před vložením dokumentu ve Kolekci .
Můžeme vygenerovat nové ObjectId vytvořením nové instance třídy :
ObjectId generatedId = new ObjectId();
Nebo můžeme také vyvolat statické get() metoda ObjectId třída:
ObjectId generatedId = ObjectId.get();
Pak už jen musíme vytvořit náš Dokument a použijte vygenerované ID. Za tímto účelem jej můžeme poskytnout v dokumentu konstruktor:
Document document = new Document("_id", generatedId);
Případně můžeme použít put() metoda:
document.put("_id", generatedId);
Při použití uživatelem vygenerovaného ID musíme být opatrní při generování nového ObjectId před každým vložením, protože duplicitní ID jsou zakázány. Duplicitní ID povedou k výjimce MongoWrite s duplicitní klíčovou zprávou.
ObjectId class poskytuje několik dalších konstruktorů, které nám umožňují nastavit některé části identifikátoru:
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)
Při použití těchto konstruktorů bychom však měli být velmi opatrní, protože jedinečnost ID poskytnutého ovladači závisí výhradně na našem kódu. V těchto konkrétních případech můžeme získat chybu duplicitních klíčů:
- pokud použijeme několikrát stejné datum (nebo časové razítko) a počítadlo
- Pokud použijeme stejný hexadecimální řetězec , bajt pole nebo ByteBuffer několikrát