【问题标题】:Append a dataframe to existing collection using mongolite R使用 mongolite R 将数据框附加到现有集合
【发布时间】:2021-03-03 03:26:00
【问题描述】:

我有一个已加载到 mongodb 的股票数据框。随着新信息的出现,我正在尝试添加每个新行都是不同日期的行。但是,当我尝试插入我的新数据框时,我收到此错误:错误:E11000 重复键错误集合:timeSeries.patimeseries index:id dup key:{_id:“5fb69a960438522a0631cca2”}

这是我目前正在做的事情

con = mongo(collection, db, url)

#look at existing data
con$find()

date         Price  Value2
2020-10-10   50      AAPL
2020-10-10   88      MSFT
2020-10-11   52      AAPL
2020-10-11   54      MSFT
                    

我在 2020 年 10 月 13 日收到了我希望插入的新数据。

print(new.df)
date        price  Value2
2020-10-12  56     AAPL
2020-10-12  92     MSFT

我要做的第一件事是从我的数据库中删除日期“2020-10-13”,然后尝试插入新信息。

con$remove(
query = '{"date" : "2020-10-12"}'
)

con$insert(
new.df
)

 Error: E11000 duplicate key error collection: timeSeries.patimeseries index: _id_ dup key: { _id: "5fb69a960438522a0631cca2" }

【问题讨论】:

    标签: r mongodb mongolite


    【解决方案1】:

    看起来您正在删除数据,而不是数据上的索引。由于日期数据被索引为 _id,因此无法删除。 (请参阅https://api.mongodb.com/wiki/current/Indexes.html#Indexes-The%5CidIndex)您是否尝试过使用更新查询,而不是尝试删除条目并在其位置创建一个新条目?

    con$update('{"date" : "2020-10-13"}', '{"$set":{"price": 56}}')
    

    有关文档,请参阅 https://jeroen.github.io/mongolite/manipulate-data.html#update-upsert

    注意:如果您正在运行查询,其中一些需要更新而另一些需要插入,如果没有找到匹配的记录,您可以添加 upsert = TRUE 以执行插入。

    更新:我没有看到任何有关执行批量更新的文档。如果不可能,一种解决方法是将每个数据帧转换为 json 字符串列表,如下所示:

    library(rjson)
    x <- split(df, 1:nrow(df))
    json_strings <- lapply(x, toJSON)
    

    在本例中,每个 json 将由作为键的列名和作为对应值的一行数据组成,因此您可以循环并执行以下操作:

    for (val in 1:length(df$date))
    {
      this_date <- df$date[val]
      date_query <- paste('{"date" : ', as.character(this_date), '}')
      set_query <- paste('{"$set":', json_strings[val], '}')
      con$update(date_query, set_query)
    }
    

    可能有一种更清洁的方法来完成所有这些工作。例如,您可以重构以便没有循环,并使用 dplyr 动词(例如 mutate)来构造 json 字符串,但想法是根据数据帧中的数据生成 json 字符串,并动态执行更新查询.

    【讨论】:

    • 嗨,马特,我已经更新了我的问题。实际上,我有一个 60 列的数据框,每次添加新数据时,我都会添加大约 500 只股票。单独设置每个数据点是不可行的。
    • 我认为该软件包不支持您想要的,但我用一种可能有效的方法更新了我的回复。
    • L,谢谢!我想我几乎用你的大部分代码都得到了它,你能澄清一下你的 for 循环中的“res1”是什么吗?
    • 应该是df。我在自己的代码中将它作为 res1 并将其更改为 df 以便清楚起见,但错过了对旧变量的引用。
    • 马特,这很好用,我不知道你为什么认为这很乱。我没有问题。非常感谢
    猜你喜欢
    • 2019-03-11
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2014-01-11
    • 2019-06-12
    • 1970-01-01
    相关资源
    最近更新 更多