Hello! I've been developing something with MongoD...
# serialization
t
Hello! I've been developing something with MongoDB, where I store store documents which share a a set of common fields and then can be one of a closed set of variants, each with its own set of specific fields. While quickly prototyping, I just had a single data class with all variant-specific fields nullable and had a
type
discriminant field + a simple enum of all variants. Very hacky, I know. Now that I'm starting to work on writing this properly, my first thought was to model this with sealed classes. Sometimes I need to filter for specific types of documents, and since it was also useful in many other places, I'd like to keep the
type
field in my sealed class. This creates a duplication of fields, however, since kx.ser adds a
type
field (or
___type
in case of a name clash, as is the case here) with the class FQN. I'd like to avoid that completely and just use the enum (serialized as its name string). Is there any way to achieve this? If not, what do you suggest I do instead? Thank you in advance 😄 asked this first here, but figured I'd ask in the more active Slack too :p
Let me know if I should send this to #CQ5JC5T0F instead.
c
Which driver are you using? KMongo, the official Kotlin driver, something else?
In theory, the
type
field does exist, so you can make queries on it. The problem is that it's not an actual field declared on the class so you won't be able to access it in a type-safe way…
I guess you could have a DTO with all possible fields + an enum to describe the type, then have your own mapper to recreate instances of the sealed class, but that's a bit of boilerplate
t
I'm using KMongo, since the official driver has poor query capabilities still (I know there is [KtMongo](https://gitlab.com/opensavvy/ktmongo), but it's not very mature).
The problem is that it's not an actual field declared on the class so you won't be able to access it in a type-safe way…
I'm not sure what you mean here. Let me know you my current code:
Copy code
@Serializable
sealed class Base {
  abstract val type: TypeEnum
  abstract val baseField: Int
}

@Serializable
class Foo(
  override val baseField: Int
  override val foo: String
) {
  override val type = TypeEnum.FOO
}

@Serializable
class Bar(
  override val baseField: Int
  override val Bar: Long
) {
  override val type = TypeEnum.BAR
}
My current issue is that kx.ser adds an extra
___type
field that it uses to discriminate the child type. I would like for it to instead use the existing
type
field.
c
I know there is KtMongo, but it's not very mature
Don't hesitate to create issues with additional features you'd like to see blob smile happy
My current issue is that kx.ser adds an extra
___type
field that it uses to discriminate the child type.
Yeah, that's the field I'm talking about. This one doesn't actually exist, so you can't use it as part of the KMongo/KtMongo DSLs.
I would like for it to instead use the existing
type
field.
I don't think this is possible at the moment (without writing your own custom serializer). Maybe they would be open to adding it, though.
t
Mmm. How would one write such a serializer?
c
Do update me if you find a solution, maybe I'll be able to add it directly to KtMongo
❤️ 1
t
Alright, I'll read on those, thanks!