java - 将 "value in array column"MongoDB 查询转换为 MongoDB Spring Data 代码

标签 java mongodb aggregation-framework spring-data-mongodb

如何使用 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" } }


<小时/> 使用 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);

关于java - 将 "value in array column"MongoDB 查询转换为 MongoDB Spring Data 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60090325/

相关文章:

java:洗牌,

Mongodb 在一次往返中执行多个查询

mongodb - 过滤掉嵌套数组中的记录 Mongodb 聚合

node.js - 如何合并MongoDB中的两个集合: Transaction and Taxes

java - 如何使用来自 Java 服务器的 JSON 将图像发送到 Javascript 客户端

java - 绘制方法在 Swing 循环中不起作用

mongodb - MongoDB 上的并发读取操作

MongoDB MapReduce : Global variables within map function instance?

mongodb - 将值转换为mongodb中的键

java - 安卓工作室 : App crashes on some phones