MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Ottieni l'ultimo ID documento inserito in MongoDB con il driver Java

1. Panoramica

A volte, abbiamo bisogno dell'ID di un documento che abbiamo appena inserito in un database MongoDB. Ad esempio, potremmo voler restituire l'ID come risposta a un chiamante o registrare l'oggetto creato per il debug.

In questo tutorial vedremo come vengono implementati gli ID in MongoDB e come recuperare l'ID di un documento che abbiamo appena inserito in una raccolta tramite un programma Java.

2. Qual è l'ID di un documento MongoDB?

Come in ogni sistema di archiviazione dati, MongoDB necessita di un identificatore univoco per ogni documento archiviato in una raccolta. Questo identificatore è equivalente alla chiave primaria nei database relazionali.

In MongoDB, questo ID è composto da 12 byte:

  • un valore di timestamp di 4 byte rappresenta i secondi dall'epoca di Unix
  • un valore casuale di 5 byte generato una volta per processo. Questo valore casuale è unico per la macchina e il processo.
  • un contatore incrementale di 3 byte

L'ID è memorizzato in un campo denominato _id ed è generato dal cliente. Ciò significa che l'ID deve essere generato prima di inviare il documento al database. Sul lato client, possiamo utilizzare un ID generato dal driver o generare un ID personalizzato.

Possiamo vedere che i documenti creati dallo stesso client nello stesso secondo avranno i primi 9 byte in comune. Pertanto, l'unicità dell'ID si basa sul contatore in questo caso. Il contatore consente a un cliente di creare oltre 16 milioni di documenti nello stesso secondo.

Sebbene inizi con un timestamp, dovremmo fare attenzione che l'identificatore non venga utilizzato come criterio di ordinamento. Questo perché non è garantito che i documenti creati nello stesso secondo siano ordinati per data di creazione, poiché non è garantito che il contatore sia monotono. Inoltre, client diversi possono avere orologi di sistema diversi.

Il driver Java utilizza un generatore di numeri casuali per il contatore, che non è monotono. Ecco perché non dovremmo utilizzare l'ID generato dal driver per l'ordinamento in base alla data di creazione.

3. L'IDOggetto Classe

L'identificatore univoco è memorizzato in un ObjectId classe che fornisce metodi convenienti per ottenere i dati archiviati nell'ID senza analizzarli manualmente.

Ad esempio, ecco come possiamo ottenere la data di creazione dell'ID:

Date creationDate = objectId.getDate();

Allo stesso modo, possiamo recuperare il timestamp dell'ID in secondi :

int timestamp = objectId.getTimestamp();

L'IDOggetto class fornisce anche metodi per ottenere il contatore, l'identificatore della macchina o l'identificatore del processo, ma sono tutti obsoleti.

4. Recupero dell'ID

La cosa principale da ricordare è che, in MongoDB, il client genera l'identificatore univoco di un Documento prima di inviarlo al cluster. Ciò è in contrasto con le sequenze nei database relazionali. Questo rende il recupero di questo ID abbastanza facile.

4.1. ID generato dal conducente

Il modo semplice e standard per generare l'ID univoco di un Documento è lasciare che sia l'autista a fare il lavoro. Quando inseriamo un nuovo Documento a una Raccolta , se non _id esiste nel Documento , il driver genera un nuovo ObjectId prima di inviare il comando di inserimento al cluster.

Il nostro codice per inserire un nuovo Documento nella tua Collezione potrebbe avere questo aspetto :

Document document = new Document();
document.put("name", "Shubham");
document.put("company", "Baeldung");
collection.insertOne(document);

Possiamo vedere che non indichiamo mai come deve essere generato l'ID.

Quando insertOne() restituisce il metodo, possiamo ottenere l'ObjectId generato dal Documento :

ObjectId objectId = document.getObjectId("_id");

Possiamo anche recuperare ObjectId come un campo standard del Documento e quindi esegui il cast su ObjectId :

ObjectId oId = (ObjectId) document.get("_id");

4.2. ID personalizzato

L'altro modo per recuperare l'ID è generarlo nel nostro codice e inserirlo nel Documento come qualsiasi altro campo. Se inviamo un Documento con un _id campo al driver, non ne genererà uno nuovo.

Potremmo richiederlo in alcuni casi in cui abbiamo bisogno dell'ID del Documento MongoDB prima di inserire il Documento nella Raccolta .

Possiamo generare un nuovo ObjectId creando una nuova istanza della classe :

ObjectId generatedId = new ObjectId();

Oppure possiamo anche invocare lo statico get() metodo dell'ObjectId classe:

ObjectId generatedId = ObjectId.get();

Quindi, non ci resta che creare il nostro Documento e utilizzare l'ID generato. Per farlo, possiamo fornirlo nel Documento costruttore:

Document document = new Document("_id", generatedId);

In alternativa, possiamo usare put() metodo:

document.put("_id", generatedId);

Quando si utilizza un ID generato dall'utente, è necessario essere cauti nel generare un nuovo ObjectId prima di ogni inserimento, in quanto sono vietati i duplicati. Gli ID duplicati risulteranno in una MongoWriteException con un messaggio chiave duplicato.

L'IDOggetto class fornisce molti altri costruttori che ci consentono di impostare alcune parti dell'identificatore:

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)

Tuttavia, dovremmo prestare molta attenzione quando utilizziamo quei costruttori poiché l'unicità dell'ID fornito al driver si basa interamente sul nostro codice. Possiamo ottenere un errore di chiavi duplicate in questi casi particolari:

  • se utilizziamo la stessa data (o timestamp) e la stessa combinazione di contatori più volte
  • Se utilizziamo la stessa Stringa esadecimale , byte array o ByteBuffer più volte