Сканирование DynamoDB возвращает несколько результатов сканирования - PullRequest
0 голосов
/ 19 марта 2020

Итак, я написал следующую функцию. Эта версия немного сокращена, и я анонимизировал данные, но критические компоненты есть.

Функция в основном берет список параметров из вызова API-шлюза, затем запрашивает дБ для каждого из них возвращает результаты.

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

Например, с одним параметром журналы функции возвращают

2020-03-19 20:27:42.974 Starting the 0 scan with 3 as the id 
2020-03-19 20:27:43.047 The 0 scan has completed successfully

С двумя параметрами журналы

2020-03-19 20:28:42.189 Starting the 0 scan with 2 as the id
2020-03-19 20:28:42.261 The 0 scan has completed successfully
2020-03-19 20:28:42.262 Starting the 1 scan with 3 as the id
2020-03-19 20:28:42.267 The 0 scan has completed successfully
2020-03-19 20:28:42.293 The 1 scan has completed successfully

И с 3 параметрами журналы

2020-03-19 20:29:49.209 Starting the 0 scan with 1 as the id
2020-03-19 20:29:49.323 The 0 scan has completed successfully
2020-03-19 20:29:49.325 Starting the 1 scan with 2 as the id
2020-03-19 20:29:49.329 The 0 scan has completed successfully
2020-03-19 20:29:49.380 The 1 scan has completed successfully
2020-03-19 20:29:49.381 Starting the 2 scan with 3 as the id
2020-03-19 20:29:49.385 The 1 scan has completed successfully
2020-03-19 20:29:49.437 The 2 scan has completed successfully

Вот код, который запускает для l oop и сканирования. Я жестко закодировал параметры и исключил некоторые не относящиеся к делу вещи

     const params = ['1','2','3'];
     for (let i = 0; i < params.length; i++) {
      console.log("Starting the " + i + " scan with " + params[i] + " as the scan parameter")
      const scanParams = {
      TableName: "Dynamo_Table",
      FilterExpression: "Org = :Org",
      ExpressionAttributeValues: { ":Org": params[i] },
      ProjectionExpression: "User_ID, Org, first_name, last_name"
     };
     await dynamoClient.scan(scanParams, function(err, data) {
      if (err) {
        console.log("data retrival failed, error logged is :" + err);
        return err;
      }
      else {
        console.log("The " + i +" scan has completed successfully")
        //console.log("data retrival successful: " + JSON.stringify(data));
        userData = userData.concat(data.Items)
        //console.log("partial data structure is " + data)
      }
    }).promise();
  }
      responseData = JSON.stringify(userData)
      console.log("Complete response is " + responseData)
      console.log("data after execution scan is " + data)

Я пытался заставить программу ждать конкуренции сканирования, определяя ожидание и используя .promise AWS ( ) функция. Однако, похоже, что они не блокируют выполнение потока. Я не уверен точно, почему он запускает несколько сканирований, хотя. Функция for l oop не выполняется больше раз, чем должна, так почему вызывается функция поиска?

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Вот пример того, как использовать DynamoDB DocumentClient для запроса нескольких элементов по ключу раздела и сбора результатов. При этом используется обещанный вариант вызова query() и ожидает выполнения всех обещаний запроса, используя Promise.all().

var AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });

const dc = new AWS.DynamoDB.DocumentClient();

// Array of organization IDs we want to query
const orgs = ['1', '2', '3'];

// Async function to query for one specific organization ID
const queryOrg = async org => {
  const params = {
    TableName: 'orgs',
    KeyConditionExpression: 'org = :o1',
    ExpressionAttributeValues: { ':o1': org, },
  };

  return dc.query(params).promise();
}

// Async IIFE because you cannot use await outside of an async function
(async () => {
  // Array of promises representing async organization queries made
  const promises = orgs.map(org => queryOrg(org));

  // Wait for all queries to complete and collect the results in an array
  const items = await Promise.all(promises);

  // Results are present in the same order that the queries were mapped
  for (const item of items) {
    console.log('Item:', item.Items[0]);
  }
})();
1 голос
/ 20 марта 2020

Всякий раз, когда вы хотите найти что-то в вашей базе данных DynamoDB, рекомендуется использовать Запрос вместо Сканирование

Это потому, что Сканирование читает каждый и каждый элемент базы данных, тогда как Query ищет только упомянутый ключ Hask (первичный ключ).

Если вы хотите искать данные с определенным «атрибутом», вы можете использовать Global Secondary Index при этом вы можете установить «атрибут» в качестве клавиши Ha sh и одновременно выбрать ключ сортировки по вашему выбору. Это может решить вашу проблему, когда таблица возвращает ответ несколько раз.

...