Hi! I've been working on a project similar to KtMo...
# opensavvy
a
Hi! I've been working on a project similar to KtMongo for a while and I no longer have the time to maintain it by myself, so I'm looking into migrating to yours. A few questions, however: • does KtMongo automatically use SerialNames for filters/aggregations/etc? Having to name a property
_id
feels incorrect to me, so I prefer annotating it with
@SerialName("_id")
instead, along with other properties. • is the
Parent::child / Child::property
syntax the only way to refer to nested properties? Using the division operator feels very hacky, how difficult would it be to implement nesting like
Parent::child { Child::property eq ??? }
c
does KtMongo automatically use SerialNames for filters/aggregations/etc?
Not currently. I'm considering making this a configurable option. Having this feature requires being compatible with all the serialization libraries people may be using, which is not something I want to attempt. Also, I'm not sure it would work on all platforms, AFAIK JS doesn't have reflection. If it's important to you, don't hesitate to create an issue with examples of what you'd expect.
is the
Parent::child / Child::property
syntax the only way to refer to nested properties?
Yes and no. It's the only safe way, but KtMongo always exposes the lower-level unsafe APIs so you can bypass the safe APIs if you really want to. For this syntax, the high-level is
Field
and the low-level is
Path
. You can create your own implementation of
Field
that generates any arbitrary
Path
you want.
Using the division operator feels very hacky
Personally, I quite like it, because it looks like a file path (
/foo/bar
) which is essentially what this is.
how difficult would it be to implement nesting like
Parent::child { Child::property eq ??? }
This is not easy because
eq
needs to know the entire chain, so
Child::property eq ???
needs to somehow know it comes from
Parent::child
. If you have context parameters, maybe something like:
Copy code
context(_: FilterQuery<T>)
inline fun <T : Any, V> Field<T, V>.invoke(
    block: FilterQuery<V>.() -> Unit,
) {
    val filter = object : FilterQuery<V> {
        // …
    }.apply(block)
}
but you will probably need to override all operators, so that's going to be quite a lot of work. However, something like`Parent::child + Child::property` or
Parent::child(Child::property)
or
Parent::child dot Child::property
etc are quite easy to add.
a
You don't need reflection to support SerialName, nor do you really have to rely on specific serialization libraries:
I'll try implementing a rough version myself to see how it'd work some time soon 🙂
c
You don't need reflection to support SerialName, nor do you really have to rely on specific serialization libraries:
Well, your screenshot is specific to KotlinX.Serialization. It won't work if people use Jackson or whatever else. Also: •
serializer<T>
can only be used within an inline reified function, meaning all path operators should be
inline
and thus wouldn't be customizable by users anymore •
getElementName(0)
← how do I know it's 0 from a
KProperty1
?