使用mongolite向MongoDB文档添加新用户的问题求助
问题描述
我正在尝试更新MongoDB中的文档,目标是在保留原有结构的前提下,向文档内插入新的用户元素,但遇到了问题。
现有MongoDB文档结构
[{ "_id": { "$oid": "648a061e7860d555a70d436a" }, "callbackUrl": "https://teste", "factors": { "q1": 50, "q2": 75.5, "q3": 30.2, "q4": 90.7, "q5": 65.3, "q6": 42.1, "q7": 80.9, "q8": 55.6, "q9": 70, "q10": 15.8 }, "users": [ { "user_id": "user1", "responses": [ {"question_id": "q1","correct": true}, {"question_id": "q2","correct": false}, {"question_id": "q3","correct": true}, {"question_id": "q4","correct": true}, {"question_id": "q5","correct": false} ] }, { "user_id": "user2", "responses": [ {"question_id": "q1","correct": true}, {"question_id": "q2","correct": true}, {"question_id": "q6","correct": false}, {"question_id": "q7","correct": true}, {"question_id": "q8","correct": true}, {"question_id": "q9","correct": false}, {"question_id": "q10","correct": false} ] } ], "TransactionId": "28eba39f-a772-447a-9916-fd81ffb9970a", "state": "created" }]
待添加的用户数据
我有一个名为data$users的JSON对象,结构如下:
[ { "user_id":"user20", "responses":[ {"question_id":"q1","correct":true}, {"question_id":"q2","correct":false}, {"question_id":"q3","correct":true}, {"question_id":"q4","correct":true}, {"question_id":"q5","correct":false} ] } ]
尝试过的方法及问题
- 使用
$set操作:会直接覆盖原有users数组,删除已存在的两个用户
con$update( query = glue::glue('{{"TransactionId": "{id}"}}'), update = glue::glue('{{"$set": {{"users": {jsonlite::toJSON(data$users, auto_unbox = TRUE)}}}}}') , upsert = TRUE )
- 使用
$push操作:会在users数组内嵌套新的数组,不符合需求
con$update( query = glue::glue('{{"TransactionId": "{id}"}}'), update = glue::glue('{{"$push": {{"users": {jsonlite::toJSON(data$users, auto_unbox = TRUE)}}}}}') , upsert = TRUE )
期望的最终结果是将新用户添加到users数组的末尾。
解决方案
问题核心是data$users本身是数组结构,直接用$push会把整个数组当作单个元素插入,而$set会直接替换字段。可以通过两种方式解决:
方法一:取出单个用户对象传入
因为当前data$users仅包含一个用户,直接提取数组中的第一个元素作为$push的参数:
con$update( query = glue::glue('{{"TransactionId": "{id}"}}'), update = glue::glue('{{"$push": {{"users": {jsonlite::toJSON(data$users[[1]], auto_unbox = TRUE)}}}}}'), upsert = TRUE )
方法二:使用$each修饰符(推荐支持批量添加)
如果后续需要添加多个用户,用$each修饰符可以直接传入用户数组,MongoDB会自动将数组内的每个元素追加到目标数组末尾:
con$update( query = glue::glue('{{"TransactionId": "{id}"}}'), update = glue::glue('{{"$push": {{"users": {{"$each": {jsonlite::toJSON(data$users, auto_unbox = TRUE)}}}}}}}'), upsert = TRUE )
问题原因说明
$set操作会直接替换整个users字段,原有数组数据会被覆盖- 直接用
$push传入数组时,MongoDB会将该数组作为单个元素插入,导致users数组出现嵌套结构
内容的提问来源于stack exchange,提问作者Araê Souza
相关产品推荐
相关产品推荐

