6

我正在尝试根据哈希中的一些预先计算的值更新 RethinkDB 中的多个文档。IE

stats给定一个带有主键的表,slug其中的数据如下

[{slug: 'foo', stats: {}}, {slug:'bar', stats:{}}]

并给出一个哈希值,如

updated_stats = {
  'foo' => {a: 1, b: 2}, 
  'bar' => {a: 3, b: 4}
}

我可以做这个

updated_stats.each{|k,v| 
  r.table('stats').get(k).update{|s| 
    { :stats => v } 
  }  
}

那么,为什么我不能执行以下操作?

r.table('stats').get_all(*updated_stats.keys).update{|s| 
  { :stats => updated_stats[s["slug"]] }  
}

rql 将 nil 显示为 updated_stats[s["slug"]] 的值。非常感谢您对此的任何帮助。谢谢。

4

2 回答 2

6

这是一个棘手的问题。

这是解决方案。

r.table('stats').get_all(*updated_stats.keys).update{|s| 
  { :stats => r.expr(updated_stats).get_field(s["slug"]) } 
}.run()

然后updated_stats是一个红宝石散列,所以当你使用括号时,它是通常的括号运算符,并且由于updated_stats没有键 s["slug"],它返回 nil。所以你必须换updated_statsr.expr()

然后 ruby​​ 中的括号用于nth,get_fieldslice。当给定一个变量时,它无法猜测应该使用哪个变量。所以你必须明确地说你想使用get_field. 我们将添加一个括号术语,它应该可以解决这个问题——参见https://github.com/rethinkdb/rethinkdb/issues/1179

对不起,你遇到了这个!

于 2014-01-31T20:09:21.267 回答
6

对于任何寻找如何批量更新记录的人来说,这实际上非常简单,但一点也不直观。

实际上,您必须执行一段insert时间来指定是否存在任何冲突,以更新这些记录。您显然需要提供要更新的每条记录的 ID。

使用以下数据集:

|-------------|--------------|
|      id     |     title    |
|-------------|--------------|
|      1      |      fun     |
|-------------|--------------|
|      2      |      in      |
|-------------|--------------|
|      3      |      the     |
|-------------|--------------|
|      4      |      sun     |
|-------------|--------------|

这是一个示例(javascript):

const new_data = [
    {id: 1, title: 'dancing'},
    {id: 4, title: 'rain'},
];

r.db('your_db').table('your_table').insert(new_data, {conflict: 'update'});

结果将是:

|-------------|--------------|
|      id     |     title    |
|-------------|--------------|
|      1      |    dancing   |
|-------------|--------------|
|      2      |      in      |
|-------------|--------------|
|      3      |      the     |
|-------------|--------------|
|      4      |      rain    |
|-------------|--------------|

但是,您应该注意的一个警告是,如果您表示new_data数组中当前不存在于表中的某些内容,它将被添加/更新

干杯!

于 2018-10-11T13:50:52.450 回答