N1QL (CB6.6) Слияние ANSI

#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 раза до физических ядер.