如何更新数组中文档的一部分? (MongoDB SpringBoot反应式)

时间:2018-07-11 22:53:30

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

我知道这个问题已经回答了一堆。但是,我还没有找到“正确”执行此操作的Spring Boot方法。我找到了示例,但无法在我的项目中使用。

<?php

$name = $_POST["name"];
$lastname = $_POST["lastname"];
$email = $_POST["email"];
$phone = $_POST["phone"];
$message = $_POST["message"];

$emailTo = "nils.kaper@outlook.com";
$subject = "Neue Nachricht über Ihr Kontaktformular";


$body ="Vorname: ";
$body.=$name;
$body.="\n";
$body.="Nachname: ";
$body.=$lastname;
$body.="\n";
$body.="E-Mail: ";
$body.=$email;
$body.="\n";
$body.="Telefon: ";
$body.=$phone;
$body.="\n";
$body.="Nachricht: ";
$body.=$message;

$success = mail($emailTo, $subject, $body, "From: ".$email);

if($success){
    echo "success";
}
else{
    echo "invalid";
}

?>

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

{"_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"}

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

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

2 个答案:

答案 0 :(得分:0)

我是个白痴。创建我的文档时,我没有发送正确的UserRoomData对象,因此从未将用户添加到Room中,这就是我退出的原因。我正确地将正确的用户添加到会议室中(正确地传递了正确的userId),并且还更改了我进行拼命更改之前的操作方式。

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);
    FindAndModifyOptions options = FindAndModifyOptions.options();
    options.returnNew(true);
    return template.findAndModify(query, update, options, RoomData.class);
}

我仍然不知道占位符如何知道要替换的正确UserRoomData。我知道在查询中我有一个eleMatch,但我不明白在查询后如何知道该替换是否有意义。我一直以为查询是要获取正确的Room对象,而不是能够获取UserRoomData对象。

编辑:以为我错了。问题归结为我将同一用户两次添加到列表中。其中一个用户更改正确,其他用户没有更改。因此,当我进行assertertEquals测试时,它返回的是不变的测试,因此未通过测试。虽然有效。我只需要删除添加同一用户。

答案 1 :(得分:0)

这是旧文章,但我希望这可以对其他人有所帮助。 更新数组内文档的最通用方法是使用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);