Функция AWS Lambda для сканирования/запроса таблицы DynamoDB с использованием значений массива как FilterExpression

вот мой случай: я пытаюсь сделать запрос к таблице (имя таблицы HCI.LocCatApp), используя значение, отправленное API как KeyConditionExpression, и я сохраняю результаты (которые должны быть числами, а не строками) в массиве, и я хочу использовать каждое значение из этого массива как FilterExpression для сканирования другой таблицы (имя таблицы HCI.Category). Итак, мне нужно зациклиться на значениях массива, взять каждое из них как FilterExpression и выполнить операцию scan. В настоящее время я пытаюсь использовать IN, но я не уверен, поддерживается ли он вообще или нет. И имейте в виду, что массив заполняется во время выполнения. А callback можно выполнить только один раз.

вот мой код:

'use strict'

var AWS = require('aws-sdk');
var mydocumentClient = new AWS.DynamoDB.DocumentClient();

exports.handler = function (event, context, callback) {

    var params = {
        TableName: 'HCI.LocCatApp',
        KeyConditionExpression : 'LocID = :lid',
            ExpressionAttributeValues: {
            ":lid": event.LocID
        },
        ProjectionExpression: 'CatID'

    };
    var catIDs = [];
    var catIDsObject = {};
    var index = 0;

    mydocumentClient.query(params, function (err, data){
        if (err) {
            callback(err, null);
        }else{
          data.Items.forEach(function(item){catIDs.push(item.CatID)});
          //callback(null, catIDs);

        }
    })

    catIDs.forEach(function(value){
      index ++;
      var catIDsKey = ":catID"+index;
      catIDsObject[catIDsKey] = value;
    })


      var params2 = {
        TableName: 'HCI.Category',
        FilterExpression : "CatID IN (:cIDs)",
        ExpressionAttributeValues : {
          ':cIDs' : catIDs
        }

      };
      mydocumentClient.scan(params2, function (err, data){
        if (err) {
            callback(err, null);
        }else{
          callback(null, data);
        }
    })

}

По какой-то причине текущий код работает успешно, но не находит совпадений, даже если я вручную заполняю значения в массиве, результатов все равно нет, операция IN похоже не работает. И большое спасибо заранее

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
533
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде catIds есть массив идентификаторов (вероятно, строк).

Когда вы передаете его в FilterExpression, вы предполагаете, что оно будет преобразовано в а) строку б) в строку в правильном формате.

FilterExpression : "CatID IN (:cIDs)",
        ExpressionAttributeValues : {
          ':cIDs' : catIDs
        }

Я не могу попробовать это сам в данный момент, но я предполагаю, что здесь запрос не работает. IN ожидает список значений, разделенных запятыми, для сравнения в скобках. Итак, после того, как массив вставлен в запрос, он должен быть таким

FilterExpression : "CatID IN (cat1, cat2, cat2)",

Но, скорее всего, он содержит дополнительный набор [ и ], и, возможно, даже преобразование массива в строку приводит к чему-то вроде [Object object] и т. д.

Одним из решений может быть использование Array.join для объединения всех элементов массива в одну строку перед ее передачей в FilterExperession. Что-то вроде этого

 FilterExpression : "CatID IN (:cIDs)",
            ExpressionAttributeValues : {
              ':cIDs' : catIDs.join()
            }

На самом деле, я просто создаю catIDs и, как вы можете видеть, я использую catIDs.push(item.CatID) для помещения значений в массив, значения являются целыми числами, и я пытаюсь снова использовать их в следующем FilterExpression как целые числа, но я Я не уверен, что это происходит, или это просто воспринимает их как строки. И я использую IN, потому что это единственное, что я мог придумать, но поскольку у меня нет предопределенных значений, которые можно было бы использовать как "CatID IN (cat1, cat2, cat2)", и поскольку массив catIDs не имеет фиксированного размера, поэтому я должен (каким-то образом ) перебирать все значения в массиве и использовать каждое по отдельности

Ghaddar_77 04.07.2019 15:39

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

Ghaddar_77 04.07.2019 15:45

@Merovingian Я отредактировал ответ и добавил конкретный пример того, что я имел в виду. Если это не сработает, вы можете перебрать массив и создать всю строку FilterExpression вручную. Это простая проблема JavaScript, не связанная с DynamoDB.

kaskelotti 04.07.2019 19:16

Я пытался работать над этим в течение достаточно долгого времени, и я пришел к выводу (возможно!) DynamoDB не будет лучшим решением для моего варианта использования, операция соединения здесь довольно сложна, и я попробовал решение, которое вы предложили (перебрать массив), и по какой-то причине я иногда получал результаты, а иногда нет, поэтому я просто решил перейти на RDS. Большое спасибо за ваш вклад.

Ghaddar_77 05.07.2019 10:43

@Merovingian Извините, что у вас так и не получилось. TBH, теперь, когда у меня наконец-то появилась возможность попробовать, я тоже не смог понять правильный синтаксис. Просто не могу понять, что не так... Я предполагаю, что нужно использовать ExpressionAttributeValues, и он должен содержать тип данных, который извлекается

kaskelotti 05.07.2019 12:10

Другие вопросы по теме