R mongolite按id使用新 Dataframe 更新集合(upsert)

pcww981p  于 2023-03-20  发布在  Go
关注(0)|答案(1)|浏览(78)

我有一个数据集存储在MongoDB集合中,即df_old
现在,我想添加新数据,即df_new,并使用它们更新集合。
所有数据均具有唯一标识符,见id列。
如果id已在集合中,则不应插入此值。否则,请插入所有其他值。
下面是我的示例代码,它创建了现有数据和新数据,并且已经将现有数据插入MongoDB数据库:

library(jsonlite)
library(tidyverse)
library(mongolite)

df_old <- tribble(
  ~id, ~colA, ~colB, ~colC, ~colD,
  1, 23, 45, "Value g", 8,
  2, 67, 56, "Value h", 3,
  3, 26, 12, "Value w", 7,
  4, 98, 85, "Value h", 9
)

df_new <- tribble(
  ~id, ~colA, ~colB, ~colC, ~colD,
  2, 67, 56, "Value h", 3,
  5, 85, 56, "Value s", 5,
  6, 23, 16, "Value t", 2
)

m = mongo(db = "DB_test",collection = "my_collection",url= "mongodb://localhost:27017")

m$insert(df_old)

现在我想将新值添加到集合中。
但是,我不确定如何指定m$update()命令。

m$update()

有人能帮帮我吗?
我想要的输出/集合应该如下所示:

# A tibble: 4 × 5
     id  colA  colB colC     colD
  <dbl> <dbl> <dbl> <chr>   <dbl>
1     1    23    45 Value g     8
2     2    67    56 Value h     3
3     3    26    12 Value w     7
4     4    98    85 Value h     9
5     5    85    56 Value s     5
6     6    23    16 Value t     2

不插入df_new中包含id=2的行,因为它已存在于集合中。

b1uwtaje

b1uwtaje1#

经过大量的反复试验,我找到了一个符合我要求的解决方案。它不是很漂亮,但它能按我想要的那样工作。
首先,必须将数据集的每一行转换为两个JSON字符串:一个只包含id,另一个包含所有值,然后将这两个向量的转置列表传递给pmap函数,该函数包含upsert命令。

df_new %>% 
  rowwise() %>% 
  group_split() %>% 
  map(., ~ c(.x %>% pull(id) ,rjson::toJSON(.x))) %>% 
  transpose() %>% 
  pmap(., ~ m$update(paste('{"id" : ', ..1, '}'), paste('{"$set":', ..2, '}'), upsert = TRUE ))

结果看起来符合预期:

> m$find() %>% tibble()

# A tibble: 8 × 5
     id  colA  colB colC     colD
  <dbl> <dbl> <dbl> <chr>   <dbl>
1     1    23    45 Value g     8
2     2    67    56 Value h     3
3     3    26    12 Value w     7
4     4    98    85 Value h     9
5     5    85    56 Value s     5
6     6    23    16 Value t     2

相关问题