spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.59k stars 1.07k forks source link

Creating a Type-Safe Query with Kotlin for Document IDs that have a relationship with DBRef #4713

Open sjiwon opened 1 month ago

sjiwon commented 1 month ago

Hello, I am developing based on Kotiln + Spring-Data-Mongo.

I left an issue because I had a question while writing Mongo Type-Safe Query using Kotlin

@Document(collection = "origins")
data class Origin(
    @Id
    val id: String = ObjectId.get().toString(),
    @DBRef
    val ref: Ref,
)

@Document(collection = "refs")
data class Ref(
    @Id
    val id: String = ObjectId.get().toString(),
)

Let's assume there's a query like this

@MongoTest
class IssueTest(
    private val mongoTemplate: MongoTemplate,
) {
    @Test
    fun execute() {
        val dummyIds = listOf<ObjectId>(
            ObjectId("665ad0ac64d2bc76ec965e68"),
            ObjectId("665ad0ac64d2bc76ec965e6b"),
            ObjectId("665ad0ac64d2bc76ec965e6e"),
        )

        // QueryA
        var criteriaA = Criteria()
        criteriaA = criteriaA.and("ref.\$id").inValues(dummyIds)

        // QueryB
        var criteriaB = Criteria()
        criteriaB = criteriaB.and(Origin::ref / Ref::id).inValues(dummyIds)

        // execute
        println("===== CriteriaA =====")
        mongoTemplate.find<Origin>(Query(criteriaA))

        println("===== CriteriaB =====")
        mongoTemplate.find<Origin>(Query(criteriaB))
    }
}
===== CriteriaA =====
16:59:23.465 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - find using query: { "ref.$id" : { "$in" : [{ "$oid" : "665ad0ac64d2bc76ec965e68"}, { "$oid" : "665ad0ac64d2bc76ec965e6b"}, { "$oid" : "665ad0ac64d2bc76ec965e6e"}]}} fields: Document{{}} for class: ...

===== CriteriaB =====
16:59:23.481 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - find using query: { "ref" : { "$in" : [{ "$oid" : "665ad0ac64d2bc76ec965e68"}, { "$oid" : "665ad0ac64d2bc76ec965e6b"}, { "$oid" : "665ad0ac64d2bc76ec965e6e"}]}} fields: Document{{}} for class: ...

The result I want is an inValues query for ref.$id like CriteriaA.

However, if use the Type-Safe Query provided by Spring-Data-Mongo + Kotlin, will get an inValues Query for ref document, not $id.

Is there a way to access ref.$id using Type-Safe Query? Did this happen because of the low version?

christophstrobl commented 2 weeks ago

Thank you @sjiwon for reporting. The issue is not related to the Type-Safe Query but appears to be general one with the mapping of in targeting dbrefs. "ref.\$id" works just because it's not targeting a property of the referenced type due to the $ prefix being present. We'll look into this.

christophstrobl commented 2 weeks ago

It turns out this issue requires a bit more time. Please use "ref.\$id" for the time being.

sjiwon commented 1 week ago

@christophstrobl Thank you for your answer. I will try to post the related pr if there is anything else to improve.

To sum it up

Is this a flow like this? I'd appreciate it if you could let me know if there's anything wrong.