Добрый день!
Есть RT индекс, который необходимо перестраивать с определённой частотой.
Данные собираются внешним приложением из разных баз. Но, есть один атрибут, для которого manticore является первичным и единственным хранилищем.
Как можно перестроить индекс, без потери этого атрибута?
Была идея создать новый индекс t1_new, заполнить его данными, а потом выполнить что-то подобное:
update t1_new set attr = (select attr from t1 where t1_new.id = t1.id);
После чего удалить старый индекс, и переименовать новый.
Но, manticore не поддерживает такой синтаксис.
Есть варианты, как перестроить индекс, с сохранением нужных полей?
Или отказаться от идеи использовать manticore в качестве первичного хранилища, и все данные держать во внешних базах?
Нельзя сделать update/replace ... select ...
, но можно сделать сперва select ... where id
, а затем replace
по id
Как-то так:
--------------
drop table if exists t
--------------
Query OK, 0 rows affected (0.01 sec)
--------------
create table t(f1 text, f2 text)
--------------
Query OK, 0 rows affected (0.01 sec)
--------------
insert into t values(1, 'original text', 'original text')
--------------
Query OK, 1 row affected (0.00 sec)
--------------
select * from t
--------------
+------+---------------+---------------+
| id | f1 | f2 |
+------+---------------+---------------+
| 1 | original text | original text |
+------+---------------+---------------+
1 row in set (0.00 sec)
--------------
select f1,f2 from t where id = 1
--------------
+---------------+---------------+
| f1 | f2 |
+---------------+---------------+
| original text | original text |
+---------------+---------------+
1 row in set (0.00 sec)
--------------
replace into t (id, f1, f2) values(1, 'original text', 'new text')
--------------
Query OK, 1 row affected (0.00 sec)
--------------
select * from t
--------------
+------+---------------+----------+
| id | f1 | f2 |
+------+---------------+----------+
| 1 | original text | new text |
+------+---------------+----------+
1 row in set (0.00 sec)
Конечно было бы здорово, если б можно было делать replace into t (id, f2) values(1, 'new text')
и f1 не менялось, но такого пока нет. Если заведёте feature request, то обсудим с командой. Техническая возможность в принципе есть. Зачем такое нужно тоже понятно, вы своим примером это демонстрируете.
Спасибо за ответ!
Я правильно понял Вашу идею, что на данный момент, единственный способ сохранить часть полей - это прочитать на уровне приложения текущий документ из индекса, а потом сделать replace
с обновлёнными и старыми (которые хотим сохранить) данными?
Мы обсудили. Собственно, самое простое, что можно сейчас сделать - это сделать плагин для Buddy, который бы принимал запрос UPDATE ... SET ...
в том случае, когда UPDATE
сам не справляется, парсил его, затем делал SELECT
по id недостающих полей и REPLACE
всей строки. В теории, это делается достаточно просто и на PHP. Атомарности не будет, но её и для просто REPLACE сейчас нет - Has the behavior of the replace statement changed? · Issue #714 · manticoresoftware/manticoresearch · GitHub
@staver не хотите сами попробовать?