'MongoDB: Unique ID per relationship

I don't have so much experience with MongoDB so for that I think it's better to try to explain my request through an example.

I have those two entities. The Tree has a list of at least one Leaf and a Leaf can't exists without a Tree.

data class Tree(
    val id: UUID,
    val name: String,
    val leaves: List<Leaf>,
)

data class Leaf(
    val id: UUID,
    val names: List<String>,
)

I would like the id of the Leaf to be unique per Tree.

For example I can have the first Tree document with a Leaf which has the id: 250bb131-2134-5667-0000-000000000000 and another Tree can has a Leaf with the same id: 250bb131-2134-5667-0000-000000000000.



Solution 1:[1]

I am assuming you want to store the Trees and Leafs in a MongoDB given the title of your question.

First, know that MongoDB has no joining, unlike a relational (SQL) database, so you have two choices:

  1. One collection. You have one Collection with all the Trees in it.
    • Tree: If you change the type of Tree.id to be BigInteger Mongo and leave the value null, Mongo will take care of allocating a unique key*.
    • You need to allocate unique keys yourself for the Leaf objects perhaps by using a Set to ensure you get a unique one
  2. Two collections. You have two collections one for Leaf and one for Tree.
    • Tree: If you change the type of Tree.id to be BigInteger Mongo and leave the value null, Mongo will take care of allocating a unique key*.
    • Leaf: If you change the type of Leaf.id to be BigInteger Mongo and leave the value null, Mongo will take care of allocating a unique key*.
    • then you have to handle the reference from Tree.leaves. This is all manual - you need change the leaves List to contain references to the Leaf object keys and handle the fetch yourself, e.g. val leaves: List<BigInteger>,. (Mongo does have a DBRef which is no more than an formal reference to database/collection/id)

*Mongo's default key is an ObjectId that will serialize into BigInteger or you could (pollute?) your code with the org.bson.types.ObjectId type. This class has some useful properties, such as sorting in datetime ascending order. But more than that you should read how such keys are generated. Unlike a central RDBMS which is responsible for allocating a lock, issuing a key, and releasing the lock - Mongo's strategy is create the primary key on the client. How could this work safely? Well: it uses a combination of date time, a client (random) key and an increment (see spec). You could this idea yourself in option 1, where you need to guarantee a unique Leaf identifier by using the ObjectId constructor

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AndrewL