Запрос DynamoDB с использованием вторичного индекса, как сделать запрос с разными ключами

Я использую безсерверный фреймворк с DynamodB [в Local]. пытаясь сделать запрос со вторичными индексированными полями. Цель состоит в том, чтобы делать запросы с помощью нескольких ключей, как мы делаем в базовых запросах поиска в Mongo: {url:'<Somevalue>'} или может быть так {url:<somevalue>,ha:<somevalue>}

Конфигурация таблицы я использую в настоящее время:

serverless.yml

resources:
  Resources:
    TableName:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        TableName: ${file(./serverless.js):Tables.TableName.name}
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: 'id'
            AttributeType: 'S'
          - AttributeName: 'url'
            AttributeType: 'S'
          - AttributeName: 'ha'
            AttributeType: 'S'
          - AttributeName: 'GSI_1_PK'
            AttributeType: 'S'
          - AttributeName: 'GSI_1_SK'
            AttributeType: 'S'
        KeySchema:
          - AttributeName: 'id'
            KeyType: 'HASH'
        GlobalSecondaryIndexes:
          - IndexName: 'GSI_1'
            KeySchema:
              - AttributeName: 'GSI_1_PK'
                KeyType: 'HASH'
              - AttributeName: 'GSI_1_SK'
                KeyType: 'RANGE'
            Projection:
              ProjectionType: 'ALL'
          - IndexName: 'URI_1'
            KeySchema:
              - AttributeName: 'url'
                KeyType: 'HASH'
            Projection:
              ProjectionType: 'ALL'
          - IndexName: 'HASH_1'
            KeySchema:
              - AttributeName: 'ha'
                KeyType: 'HASH'
            Projection:
              ProjectionType: 'ALL'

  Outputs:
    TableNameARN:
      Value: { 'Fn::GetAtt': [TableName, Arn] }
      Export:
        Name: ${file(./serverless.js):Exports.TableNameARN}

с этим, в настоящее время я могу искать только с id поле,

Q:

1> Какие изменения необходимо внести в запрос с разных полей? [который вторично индексируется, без использования id в запросе]

2> Как мне искать с несколькими атрибутами? [то есть: {url:<somevalue>,ha:<somevalue>}]

Запрос я использую:

var params = {
    TableName: '<TableName>',
    IndexName:'URI_1',
    Key: {
      url: 'http://something.com'
    }
};
docClient.get(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

Вывод запроса:

{
message:"One of the required keys was not given a value",
code:"ValidationException,
...
}

1 ответ

Решение
  • Вы уже использовали GSI, который позволяет вам использовать вторичные индексы. Но ты должен использовать query вместо get это позволяет вам запрашивать любую таблицу или вторичный индекс, который имеет составной первичный ключ (ключ раздела и ключ сортировки).
  • Просто используйте FilterExpression а также ExpressionAttributeValues, он поддерживает использование нескольких условий.

var params = {
    TableName: '<TableName>',
    IndexName : 'URI_1',
    KeyConditionExpression : 'url = :url',
    FilterExpression : 'ha = :ha',
    ExpressionAttributeValues : {
      ':url': 'http://something.com',
      ':ha': 'aaaa'
    }
};
docClient.query(params, function(err, data) {
    if (err) console.log(err); // an error occurred
    else console.log(data); // successful response
});

дополнительный

Там три выражения, которые мы могли бы использовать для запроса условий, первые два из них используются для Dynamodb.query и последний используется для Dynamodb.updateItem или же Dynamodb.putItem:

  • KeyConditionExpression - где вам нужно указать ключ раздела - обязательно - или ключ сортировки. Он может поддерживать ключ таблицы только по умолчанию, если вы хотите использовать индексы, такие как GSI, вы должны использовать его с IndexName.
  • FilterExpression - применяется после завершения запроса, но до возвращения результатов, а FilterExpression не может содержать атрибуты ключа раздела или ключа сортировки.
  • ConditionExpression - Условие, которое должно быть выполнено для успешного выполнения условного обновления.