我有一个具有标签列表的MongoDB实体:
@Document
@TypeAlias("project")
data class Project(@Id var id: String?,
val name: String,
val tags: MutableList<Tag>)
我想寻找包含标签子集的Project。
例如,给定这些proyects:
projectService.save(Project(null, "someProject11",
mutableListOf(Tag("area","IT"), Tag("department","Architecture"))))
projectService.save(Project(null, "someProject12",
mutableListOf(Tag("area","IT"), Tag("department","HR"))))
如果我按以下方式定义存储库:
interface ProjectRepository : ReactiveCrudRepository<Project, String> {
fun findByTags(tags : List<Tag>): Flux<Project>
}
寻找子集不起作用,例如:的项目Tag("area","IT")
应返回两个结果,但实际上返回0。底层的mongo查询为:
{"find": "project", "filter": {"tags": [{"key": "area", "value": "IT"}]}
它只能通过列表的完整内容listOf(Tag("area","IT"), Tag("department","Architecture"))
:
{"find": "project", "filter": {"tags": [{"key": "area", "value": "IT"},{"key": "department", "value": "Architecture"}]}
如何查询包含列表子集的实体?
使用Criteria
和$elemMatch
运算符解决:
interface CustomProjectRepository {
fun findByTags(tags: List<Tag>): Flux<Project>
}
class CustomProjectRepositoryImpl(private val mongoTemplate: ReactiveMongoTemplate) : CustomProjectRepository {
override fun findByTags(tags: List<Tag>): Flux<Project> {
val query = Query()
val criterias = mutableListOf<Criteria>()
tags.forEach {
criterias.add(Criteria.where("tags").elemMatch(Criteria.where("key").`is`(it.key).and("value").`is`(it.value)))
}
query.addCriteria(Criteria().andOperator(* criterias.toTypedArray()))
return mongoTemplate.find(query, Project::class.java)
}
}
interface ProjectRepository : ReactiveCrudRepository<Project, String>, CustomProjectRepository {
fun findByClientIdAndId(clientId: String, id: String): Mono<Project>
fun findByClientId(clientId: String): Flux<Project>
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句