我正在使用R mongolite读取和写入具有以下结构的mongo集合:
[{_id: 1, name: a, sites: [
{ref: site_a1},
{ref: site_a2}
]},
{_id: 2, name: b, sites: [
{ref: site_b1},
{ref: site_b2}
]},
{_id: 3, name: c, sites: [
{ref: site_c1},
{ref: site_c2},
{ref: site_c3},
{ref: site_c4}
]}]
对于我的集合的给定文档,我想为每个站点添加一些属性。例如,我想像这样更新第一个文档:
{_id: 1, name: a, sites: [
{ref: site_a1, lat: 10, lng: 20},
{ref: site_a2, lat: 5, lng: 40}
]}
在mongolite中,我能够将网站作为数据框并计算所需的属性:
sites <- db$find(query = '{"name": 1}',
fields='{"_id": 0, "name": 0}')$sites[[1]]
loc <- getLatLng(sites)
# loc is a dataframe with lat and lng for each site
但是我找不到更新数据库的方法。我试过了:
db$update(query = '{"name": 1}',
update = paste0('{"$push":{"sites": {"$each":',jsonlite::toJSON(loc),'}}}'),
upsert = FALSE, multiple = FALSE)
毫不奇怪地给了我:
{_id: 1, name: a, sites: [
{ref: site_a1},
{ref: site_a2},
{lat: 10, lng: 20},
{lat: 5, lng: 40}
]}
有没有办法通过将新属性添加到arry的现有元素来更新sites字段,还是应该用$set
替换整个站点字段?谢谢你的帮助。
我想我的问题与this question有关,所以我可能需要遍历我的数组中的每个元素......
答案 0 :(得分:2)
以下似乎可以解决问题:
sites <- db$find(query = '{"name": 1}',
fields='{"_id": 0, "name": 0}')$sites[[1]]
loc <- getLatLng(sites)
for (i in 1:nrow(sites)){
db$update(query = paste0('{"name": 1, "sites.ref":', sites$ref[i],'}'),
update = paste0('{"$set":{"sites.$.lat":',loc[i, "lat"],'},
"$set":{"sites.$.lon":',loc[i, "lng"],'}}'))
}
仍然感兴趣,如果有更好的方式...