在R中使用mongolite提取MongoDB数组元素的方法咨询
在R中使用mongolite将MongoDB嵌套数组转换为宽表结构
你提到的需求可以通过mongolite的$find或$aggregate方法实现,两种方法的适用场景和构造方式如下:
方法一:使用$find方法(简洁投影)
如果仅需要完成字段投影(提取嵌套数组中的分数为单独列),$find方法更直接,只需在第二个参数(fields)中定义投影规则即可,和你在MongoDB Compass中写的逻辑一致:
library(mongolite) # 连接目标MongoDB集合 col <- mongo(collection = "your_collection_name", db = "your_database_name", url = "mongodb://localhost:27017") # 执行find查询,构造投影参数 result_find <- col$find( query = '{}', # 空查询表示匹配所有文档 fields = '{ "_id": 1, "date": 1, "question_a_score": { "$arrayElemAt": ["$dailyAnswer.score", 0] }, "question_b_score": { "$arrayElemAt": ["$dailyAnswer.score", 1] }, "question_c_score": { "$arrayElemAt": ["$dailyAnswer.score", 2] } }' ) # 输出结果 print(result_find)
说明:fields参数是JSON格式字符串,"_id":1和"date":1表示保留原文档的这两个字段,后续三个字段通过$arrayElemAt提取dailyAnswer.score数组对应位置的元素。
方法二:使用$aggregate方法(灵活扩展)
如果后续需要添加更多数据处理步骤(如过滤、分组、排序等),$aggregate更适合,通过构造聚合管道实现投影:
# 构造聚合管道(仅包含$project阶段) pipeline <- '[ { "$project": { "_id": 1, "date": 1, "question_a_score": { "$arrayElemAt": ["$dailyAnswer.score", 0] }, "question_b_score": { "$arrayElemAt": ["$dailyAnswer.score", 1] }, "question_c_score": { "$arrayElemAt": ["$dailyAnswer.score", 2] } } } ]' # 执行聚合查询 result_agg <- col$aggregate(pipeline) # 输出结果 print(result_agg)
说明:聚合管道是一个JSON数组,这里仅使用了$project阶段实现和find方法相同的投影效果,后续可在管道中追加$match、$group等阶段扩展功能。
关键注意事项
当前的$arrayElemAt依赖dailyAnswer数组中question的固定顺序(a、b、c依次排列),如果数组中question的顺序可能变化,建议改用$filter精准匹配question字段,避免取错分数:
例如,修改question_a_score的计算逻辑:
"question_a_score": { "$getField": { "field": "score", "input": { "$arrayElemAt": [{ "$filter": { "input": "$dailyAnswer", "cond": { "$eq": ["$$this.question", "a"] } } }, 0] } }
将上述逻辑替换到fields或聚合管道的$project中即可,确保无论数组顺序如何,都能正确提取对应question的分数。
内容的提问来源于stack exchange,提问作者tktk234
相关产品推荐
相关产品推荐

