如何使用 Java MongoDB Spring Data 驱动程序将以下 MongoDB 查询转换为基于 Java 的查询?
db.User.aggregate([
{ $match : { $expr: { $in: [ "ADMIN", "$roles" ] } } },
{ $sort : { "createdAt": 1 } },
{ $limit : 1 }
])
我在 Kotlin 中尝试的解决方案,我认为这是错误的(我不知道如何指定“角色”是用户文档中的一个字段)。
fun queryFirstAdmin(): User? {
val matchRolesOpt = Aggregation.match(Criteria.where("ADMIN").`in`("roles"))
val sortOpt = Aggregation.sort(Sort.Direction.ASC, "createdAt")
val limitOpt = Aggregation.limit(1)
var ops: MutableList<AggregationOperation> = mutableListOf()
ops.add(matchRolesOpt)
ops.add(sortOpt)
ops.add(limitOpt)
var aggregation = Aggregation.newAggregation(*ops.toTypedArray())
val aggregationResult = mongoTemplate.aggregate(aggregation, User::class.java, User::class.java)
return aggregationResult.uniqueMappedResult
}
此解决方案有效,但不幸的是它返回用户文档的一部分(因为它已展开):
fun queryFirstAdmin(): User? {
val unwindOpt = Aggregation.unwind("roles")
val matchRolesOpt = Aggregation.match(Criteria.where("roles").`is`("ADMIN"))
val sortOpt = Aggregation.sort(Sort.Direction.ASC, "createdAt")
val limitOpt = Aggregation.limit(1)
var ops: MutableList<AggregationOperation> = mutableListOf(unwindOpt, matchRolesOpt, sortOpt, limitOpt)
var aggregation = Aggregation.newAggregation(*ops.toTypedArray())
val aggregationResult = mongoTemplate.aggregate(aggregation, User::class.java, User::class.java)
return aggregationResult.uniqueMappedResult
}
即如果返回的文档具有数组 ["ADMIN"] 但原始文档的 "roles"字段中有 ["ADMIN","USER]
我该如何解决这个问题?
最佳答案
用于聚合的 MongoDB Spring Data Java 代码:
MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "test");
Aggregation agg = newAggregation(
match(where("roles").is("ADMIN")),
sort(ASC, "createdAt"),
limit(1L)
);
AggregationResults<Document> results = mongoOps.aggregate(agg, "User", Document.class);
results.forEach(System.out::println);
注意:
聚合中的匹配阶段
{ $match : { $expr: { $in: [ "ADMIN", "$roles" ] } } }
可以用这个替换,结果是一样的:
{ $match : { roles: "ADMIN" } }
Bson match = match(expr( Document.parse(" { $in: [ 'ADMIN', '$roles' ] } ")));
// -or-
// Bson match = match(eq("roles", "ADMIN"));
List<Bson> pipeline =
Arrays.asList(match, sort(ascending("createdAt")), limit(1));
List<Document> results = new ArrayList<>();
collection.aggregate(pipeline).into(results);
results.forEach(System.out::println);
关于java - 将 "value in array column"MongoDB 查询转换为 MongoDB Spring Data 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60090325/