java - How do you remove an element from an array based on element's field value? (Spring-Boot, Reactive MongoDB)
问题描述
I have a Room object. It is essentially a DTO. It has a List or MongoDB an array of User Objects.
For the life of me I can't figure out how to remove a user from the array based on the user's id and couple other things (roomId, roomLeaderId).
public Mono<RoomData> findAndTryKickUser(String roomId, String requestUserId,
String kickUserId){
Query query = new Query();
query.addCriteria(Criteria.where("id").is(roomId).and("roomLeaderId").is(requestUserId)
.and("userRoomDatas").elemMatch(Criteria.where("userId").is(kickUserId)));
Update update = new Update();
update.pull("userRoomDatas.$.userId", kickUserId);
FindAndModifyOptions options = FindAndModifyOptions.options();
options.returnNew(true);
return template.findAndModify(query, update, options, RoomData.class);
}
Now I do have the option to make a User object and place the id in and try to remove the user that way (I haven't tried it yet, but I think that would work), but from my understanding of the placeholder "$" I should be able to remove element.
{"_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"}
EDIT: I made some edits to the code. In part of experimenting with unset but I realized id is actually userId for UserRoomData. Still erroring out in my JUnit tests.
org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 2: 'Cannot apply $pull to a non-array value' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "Cannot apply $pull to a non-array value", "code" : 2, "codeName" : "BadValue" }; nested exception is com.mongodb.MongoCommandException:
解决方案
$pull 是数组运算符,它使用查询来匹配和删除嵌入数组中的匹配行。
就像是
public Mono<RoomData> findAndTryKickUser(String roomId, String requestUserId, String kickUserId){
Query query = new Query();
query.addCriteria(Criteria.where("id").is(roomId).and("roomLeaderId").is(requestUserId)
.and("userRoomDatas").elemMatch(Criteria.where("userId").is(kickUserId)));
Update update = new Update();
update.pull("userRoomDatas", new Query().addCriteria(Criteria.where("userId").is(kickUserId)));
FindAndModifyOptions options = FindAndModifyOptions.options();
options.returnNew(true);
return template.findAndModify(query, update, options, RoomData.class);
}
参考
推荐阅读
- python - Pytorch - TypeError: ToTensor() 使用 torchvision.transform 不接受任何参数
- asp.net - 如何将 LightInject 与 Web 表单一起使用?
- linux - 使用 Vagrant 和 Virtual box 创建开发服务器时出错
- bash - 加入的意外问题
- cpu-architecture - 为什么看存储的电影不慢
- windows - 在 AWS 如何将“Microsoft Windows Server 2016”服务器实例迁移到“Microsoft Windows Server 2016 with SQL Server 2017 Standard”?
- node.js - 使用 nodejs 正则表达式查找 ksh 函数
- python - 限制特定 pyparsing 表达式中的新行
- algorithm - 如何实施 SAT 求解器以进行 kSAT 练习?
- python - 使用一行转换列表中所有元素的属性类型