#couchbase #n1ql
Вопрос:
Я пытаюсь извлечь идентификатор клиента из «:ao.mos:pro:%» и обновить соответствующий документ «:pd:pro:%», у нас есть тысячи «:ao.mos:pro:%» документов и соответствующих «:pd:pro:%» для каждого документа mo:pro.
Я использую приведенный ниже запрос, и он работает, но он обновляет только один документ, в котором он может найти индексы.
MERGE INTO `bucket1` AS d
USING `bucket1` AS p
ON d.icc = p.icc AND META(d).id LIKE ':pd:pro:%' AND META(p).id LIKE ':ao.mos:pro:%'
WHEN MATCHED THEN
UPDATE SET d.customerId = p.customerId;
Любые предложения о том, как заставить это работать для всех соответствующих документов в корзине.
Комментарии:
1. Он обновит все соответствующие документы (ПРИМЕЧАНИЕ: Он не изменит один и тот же документ снова ). Проверьте свое состояние d.icc = p.icc. Также blog.couchbase.com/ansi-join-enhancements-and-ansi-merge
2. Я проверял это несколько раз, только одно количество мутаций, и, по-видимому, всегда обновляется один и тот же документ.. Только когда я изменяю оператор Like с помощью клавиш use, я могу принудительно изменить другой идентификатор
Ответ №1:
Следующие работы.
CREATE INDEX ix11 ON `default` (icc, customerId) WHERE META().id LIKE ":ao.mos:pro:%";
CREATE INDEX ix12 ON `default` (icc, customerId) WHERE META().id LIKE ":pd:pro:%";
INSERT INTO default VALUES(":ao.mos:pro:1", {"icc":1, "customerId":100});
INSERT INTO default VALUES(":ao.mos:pro:2", {"icc":2, "customerId":101});
INSERT INTO default VALUES(":pd:pro:1", {"icc":1});
INSERT INTO default VALUES(":pd:pro:2", {"icc":1});
INSERT INTO default VALUES(":pd:pro:3", {"icc":2});
MERGE INTO `default` AS m
USING (SELECT p1.icc, p1.customerId
FROM `default` AS p1
WHERE META(p1).id LIKE ':ao.mos:pro:%' AND p1.icc IS NOT NULL) AS p
ON m.icc = p.icc AND META(m).id LIKE ':pd:pro:%'
WHEN MATCHED THEN
UPDATE SET m.customerId = p.customerId;
MERGE INTO `default` AS m
USING default AS p
ON m.icc = p.icc AND META(m).id LIKE ':pd:pro:%' AND META(p).id LIKE ':ao.mos:pro:%'
WHEN MATCHED THEN
UPDATE SET m.customerId = p.customerId;
У вас возникли следующие проблемы:
Первая исходная строка соответствует 2 целевым строкам. Второй источник соответствует одной и той же целевой строке (изменив значение icc на 1 для ключа документа «:ao.mos:pro:2»), затем возвращает ошибку (5320 Многократных ОБНОВЛЕНИЙ/УДАЛЕНИЯ одного и того же документа (ключ документа «xxx») в инструкции СЛИЯНИЯ) (как и при частичном обновлении строк, вам нужны транзакции, которые ничего не хотят обновлять), так как вы не можете обновить одну и ту же строку снова. Чтобы решить эту проблему, вам необходимо изменить пункт «ВКЛЮЧЕНО».
Ответ №2:
Если это одноразовая операция, вы можете использовать службу событий и создать функцию с псевдонимом корзины «src_bkt» для сопоставления с корзиной 1 в режиме r w, а граница канала развертывания, установленная на «Из всего», может легко быстро выполнять 100 миллионов элементов без индексов.
function OnUpdate(doc,meta) {
// Filter out all non-interesting items
if (!meta.id.startsWith(":pd:pro:")) return;
// No need to do anything already updated.
if (doc.customerId)return;
var myint = meta.id.substring(8);
var otherkey = ":ao.mos:pro:" myint;
var otherdoc = src_bkt[otherkey];
if (otherdoc) {
if (doc.icc === otherdoc.icc ) {
// update the field as we have a match and it is missing.
doc.customerId = otherdoc.customerId;
src_bkt[meta.id] = doc;
}
}
}
Так что теперь вы просто вставляете некоторые тестовые документы, используя QWB
INSERT INTO bucket1 VALUES(":ao.mos:pro:1", {"icc":1, "customerId":100});
INSERT INTO bucket1 VALUES(":ao.mos:pro:2", {"icc":2, "customerId":101});
INSERT INTO bucket1 VALUES(":pd:pro:1", {"icc":1});
INSERT INTO bucket1 VALUES(":pd:pro:2", {"icc":1});
INSERT INTO bucket1 VALUES(":pd:pro:3", {"icc":2});
Затем проверьте документы, которые у вас должны быть
:ao.mos:pro:1{"customerId":100,"icc":1}
:ao.mos:pro:2{"customerId":101,"icc":2}
:pd:pro:1{"icc":1}
:pd:pro:2{"icc":1}
:pd:pro:3{"icc":2}
Разверните функцию события и еще раз просмотрите свои документы.
:ao.mos:pro:1{"customerId":100,"icc":1}
:ao.mos:pro:2{"customerId":101,"icc":2}
:pd:pro:1{"icc":1,"customerId":100}
:pd:pro:2{"icc":1}
:pd:pro:3{"icc":2}
Как и ожидалось, обновлен только один документ с соответствующими ключами и соответствующими свойствами icc.
Для повышения производительности (делая миллионы) вы можете увеличить число рабочих в настройках функций в 2 раза до физических ядер.