将“数组列中的值”转换为MongoDB查询到MongoDB Spring数据代码

问题描述 投票:0回答:3

如何使用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”],但是原始文档的“角色”字段中具有[“ ADMIN”,“ USER]

我该如何解决?

java mongodb aggregation-framework spring-data-mongodb
3个回答
0
投票
<< [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" } }

使用MongoDB Java Driver的相同查询:

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);


0
投票
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 }

0
投票
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”],但是原始文档的“角色”字段中具有[“ ADMIN”,“ USER]

我该如何解决?
© www.soinside.com 2019 - 2024. All rights reserved.