使用 Spring 数据 MongoDB 从 MongoDB 中的嵌入式数组中查找包含元素子列表的实体
Find entities containing a sublist of elements from an embedded array in MongoDB with Spring Data MongoDB
我有一个 MongoDB 实体,它有一个标签列表:
@Document
@TypeAlias("project")
data class Project(@Id var id: String?,
val name: String,
val tags: MutableList<Tag>)
我想查找包含标签子集的项目。
例如给定这些项目:
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")
的项目应该 return 两个结果但实际上 returns 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>
}
我有一个 MongoDB 实体,它有一个标签列表:
@Document
@TypeAlias("project")
data class Project(@Id var id: String?,
val name: String,
val tags: MutableList<Tag>)
我想查找包含标签子集的项目。
例如给定这些项目:
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")
的项目应该 return 两个结果但实际上 returns 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>
}