Recommended approach to direct relations

45 views
Skip to first unread message

Gareth Coles

unread,
Nov 20, 2022, 8:35:20 AM11/20/22
to kmongo
What's the recommended way to approach relationships between collections in KMongo?

For the sake of argument, let's assume an object like the following, using kotlinx.serialization:

@Serializable
data class Grouping(
    val _id: Id<Grouping> = newId(),

    // Relations
    val cases: MutableList<@Contextual Id<Case>> = mutableListOf(),
    val users: MutableList<@Contextual Id<User>> = mutableListOf(),

    // Properties
    val createdAt: Instant,
    var comment: String,
    var name: String,
)


This appears to be what KMongo expects of us. However, I'm not sure what the best approach is here to create an object that contains the matching Case and User documents from the database in a single query. Additionally, I'm not sure how to represent them for storage.

I feel like this should be a common use-case for KMongo, but I can't seem to find anything useful in the docs.

zigzago

unread,
Nov 24, 2022, 1:39:28 AM11/24/22
to kmongo
Hello,

You have to be cautious with relationships using MongoDB - potentiel perf bottleneck here !
MongoDB is a Document database, so if you can store Cases an Users in Grouping collection, just do it !

If you really need more than one collection, then you have to insert first Cases and Users (may be with bulkWrite https://litote.org/kmongo/dokka/kmongo/org.litote.kmongo/com.mongodb.client.-mongo-collection/bulk-write.html) and then insert Grouping.


HTH

Gareth Coles

unread,
Nov 24, 2022, 4:11:36 AM11/24/22
to kmongo
Thanks for the response, I appreciate it!

Unfortunately, I don't think embedding Cases and Users within the Grouping documents will work out, as these lists are unbounded, and both types of document will need to be updated often.

Thanks for the tip on bulkWrite, I can definitely see how this would be useful. However, I'm more curious about how the relationship should be represented in my data model, and how to retrieve the data using KMongo once it's already been stored.

If the class above represents what's actually stored in the database, does that mean I need another class that replaces the Id<*> references with references to the other document types in the database? If so, that's okay, I'm just wondering if there's a better approach.

zigzago

unread,
Nov 27, 2022, 3:19:32 PM11/27/22
to kmongo
You can add a method to Grouping:

data class Grouping(...) {
 fun loadCases() : List<Case> = colCases.find(Case:_id `in` cases) //you can even cache the result if cases is a List and not a MutableList

Gareth Coles

unread,
Nov 28, 2022, 10:06:15 AM11/28/22
to kmongo
Ah, okay, I see what you're getting at. If that's the canonical approach, then you're surely right about performance too - I think I've got some thinking to do.

Many thanks for the help!

Reply all
Reply to author
Forward
0 new messages