java - 如何更新数组内文档的一部分? (MongoDB Spring Boot 响应式(Reactive))

标签 java spring-boot mongodb-query reactive-programming

我知道这个问题已经得到了很多答案。但是,我还没有找到“正确”执行此操作的 Spring Boot 方法。我找到了示例,但无法让它适用于我的项目。

{"_id":"5b45572047f84e3d10c59b8a"
,"userRoomDatas":[{"isInGame":false,"isReady":true,"isSpectator":false,"userId":"5b45572047f84e3d10c59b84"}]
,"selectedScreen":"MATCHMAKING"
,"privacySetting":"PUBLIC"
,"roomLeaderId":"5b45572047f84e3d10c59b84"
,"botHostId":"5b45572047f84e3d10c59b84"
,"matchmakingData":   {"selectedQueId":"5b45572047f84e3d10c59b85","matchmakingRating":"M3"}
,"currentRoomStatus":"IN_ROOM"
,"canStartSearch":false
,"password":"AA=="
,"quickJoinEnabled":true
,"roomRating":"MEMERS_ONLY"
,"_class":"room"}

这是我的文档。我希望能够更改 userRoomDatas 中对象之一的值。例如“isSpectator”:false到“isSpectator”:true

public Mono<RoomData> findAndModifyUserSpectate(String roomId, String requestUserId,
        boolean isSpecator){
    Query query = new Query();
    query.addCriteria(Criteria.where("id").is(roomId).and("userRoomDatas")
            .elemMatch(Criteria.where("userId").is(requestUserId)));
    Update update = new Update();
    update.set("userRoomDatas.$.isSpectator : " + isSpecator, new Query(Criteria
            .where("userRoomDatas").elemMatch(Criteria.where("userId").is(requestUserId))));
    FindAndModifyOptions options = FindAndModifyOptions.options();
    options.returnNew(true);
    return template.findAndModify(query, update, options, RoomData.class);
}

这是我得到的最好的。我尝试过不同的方法,但我知道它们都是错的。

根据我的理解,第一个查询过滤掉了我的 RoomData 对象。但更新部分我不知道如何引用数组内的文档并告诉它用新值更新其中一个变量。我知道关键部分没有多大意义。我尝试了不同的方法,但我不知道在哪里放置带有值的查询。

最佳答案

这是一篇旧文章,但我希望这可以帮助其他人。 更新数组内文档的最通用方法是使用 MongoDB arrayFilters 。使用 springboot 没有使用 MongoTemplate 的直接连接,但可以使用 MongoDatabase 对象。

一个实际的例子很简单。假设有一个类似的文档

{ _id: "132456",
  statistics:
    2018: [
      {
         offset: 5,
         results: {
            a: 1,
            b: 2
         }
      },
      {
         offset: 4,
         results: {
            a: 13,
            b: 24
         }
      }
    ]
}

更新的 Java 代码如下所示

// Defines the query which selects the document
Bson filter = Filters.and(Filters.eq("_id", "132456"), Filters.exists("statistics"));

// Defines the udpate command. Notice the filtered positional operator $[element]
Bson update = Updates.set("statistics.$[element].results.b", result);

// IMPORTANT! This select the document into the array. 
// Notice that the document does not really contain a key called "element": 
// it is only a parametric variable later referenced in the arrayFilters
UpdateOptions updateOptions = new UpdateOptions();
List<Bson> arrayFilters = new ArrayList();
Bson arrayElement = Filters.eq("element.daysOffset", -4);
arrayFilters.add(arrayElement);
updateOptions.arrayFilters(arrayFilters);

// Finally update the element matching both the document in the collection 
// and the document in the inner array
mongoTemplate.getDb().getCollection("MyCollection").updateOne(filter, update, updateOptions);

关于java - 如何更新数组内文档的一部分? (MongoDB Spring Boot 响应式(Reactive)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51295212/

相关文章:

java - 如何获取返回结果的服务器的数据,我想获取该结果以更新到另一台服务器

java - 如何在 Eclipse 中使用条件断点?

java - Thymeleaf 的布局 :fragment not working after packaged in jar

java - 提供了至少 2 个参数,但按使用规范和排序查询时仅存在 1 个参数

mongodb - 带过滤器的 Mongo 日期范围索引

mongodb - $unwind 2个字段分别在mongodb查询中

Java Servlet 映射。欢迎文件列表

java - Gradle 不会将 JNI *.so 库打包到 APK 文件中

java - Spring 启动 : Get current user's username

java - 有没有办法在配置有两个 mongo 数据库的 springboot 应用程序中使用 MongoOpeations