Массовое обновление в RethinkDB

Я пытаюсь обновить несколько документов в RethinkDB на основе некоторых предварительно рассчитанных значений в хеше. то есть

Учитывая таблицу 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 показывает ноль в качестве значения updated_stats[s["slug"]]. Был бы очень признателен за любую помощь в этом. Спасибо.


person svs    schedule 31.01.2014    source источник


Ответы (2)


Это сложная проблема.

Вот первое решение.

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_stats в r.expr().

Затем скобки в рубине используются для nth, get_field, slice и т. д. И когда ему дана переменная, он не может угадать, какую из них следует использовать. Поэтому вы должны явно сказать, что хотите использовать get_field. Мы добавим термин в квадратных скобках, который должен решить эту проблему — см. https://github.com/rethinkdb/rethinkdb/issues/1179

Извините, что вы столкнулись с этим!

person neumino    schedule 31.01.2014
comment
Это в JavaScript с rethinkdbdash. Пропустите соединение, если вы используете официальный драйвер. - person neumino; 17.07.2016

Для тех, кто ищет, как массово обновлять записи, это на самом деле довольно просто, но совсем не интуитивно понятно.

На самом деле вам нужно выполнить insert, указав, что если есть какие-либо конфликты, чтобы обновить эти записи. Очевидно, вам нужно будет указать идентификатор каждой записи, которую нужно обновить.

Используя следующий набор данных:

|-------------|--------------|
|      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 что-то, чего в данный момент нет в таблице, это будет добавлено/заменено.

Ваше здоровье!

person KyleFarris    schedule 11.10.2018
comment
Ура, ты спас мне жизнь! Это то, что я искал. К сожалению, в официальных документах это явно не определено. - person iedmrc; 02.01.2020