Запросить глобальный вторичный индекс, используя содержащийся в DynamoDB локальный - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть id в качестве хеш-ключа моей таблицы и returnItemId, который является GSI.returnItemId - это строка, содержащая значения, разделенные запятыми.Учитывая номер для GSI, я хочу иметь возможность запросить и получить правильный элемент, который содержит его, используя contains

var params = {
    "AttributeDefinitions": [ // describbes the key schema of the table
    {
      "AttributeName": "id",
      "AttributeType": "S"
    },
    {
      "AttributeName": "returnItemId",
      "AttributeType": "S"
    }
  ],
  // Hash for Primary Table
  "KeySchema": [
    {
      "AttributeName": "id",
      "KeyType": "HASH"
    }
  ],

  "GlobalSecondaryIndexes": [
    {
      "IndexName": "ReturnItemIndex",
      "KeySchema": [
        {
          "AttributeName": "returnItemId", //must match one of attributedefinitions names
          "KeyType": "HASH"
        }
      ],
      "Projection": {
        "ProjectionType": "ALL"
      },
      "ProvisionedThroughput": {
        "ReadCapacityUnits": 5,
        "WriteCapacityUnits": 5
      }
    }
  ],

  "ProvisionedThroughput": {
    "ReadCapacityUnits": 5,
    "WriteCapacityUnits": 5
  },


  "TableName": "my-table"
};
dynamodb.createTable(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response

});

Тогда я собираюсь создать 2 элемента

var params = {
    TableName: 'my-table',
    Item: { 
    
        "id": "the_first_item",
        "returnItemId": "123,456,789"
    },
};
docClient.put(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

И второй элемент

var params = {
    TableName: 'my-table',
    Item: { 
    
        "id": "the_second_item",
        "returnItemId": "987,654,321"
    },
};
docClient.put(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

Эти два элемента выглядят как enter image description here

Я пытаюсь выполнить запрос и получить правильный элемент, который содержит 987 используя следующий запрос.Поскольку мой первый элемент имеет 123,456,789, а второй элемент имеет 987,654,321, этот метод должен вернуть второй элемент.

var params = {
    TableName: 'my-table',
    IndexName: 'ReturnItemIndex', // optional (if querying an index)
    KeyConditionExpression: 'contains(returnItemId, :return_id)',
    //FilterExpression: 'contains(returnItemId, :return_id)', // a string representing a constraint on the attribute
    ExpressionAttributeValues: { ':return_id': '987' },
};
docClient.query(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

Но я получаю сообщение об ошибке, содержащееся в выражении ключа.Возможен ли этот метод?

1 Ответ

0 голосов
/ 24 апреля 2019

contains можно использовать только в фильтрах, что означает:
- операции запроса или сканирования пройдут все данные, чтобы применить ваши фильтры
- Ваша стоимость операций чтения будет включать в себя все прочитанные данные, а не только сопоставленные данные
- с содержит «12», вы, вероятно, также сопоставили бы «123» и «124»
- лучше, чем разделенный запятыми, использовать тип данных StringSet или NumberSet

Я бы предложил другой макет
Keyschema:
Ключ партитуры: id
Ключ сортировки: returnItemId
GSI
Ключ раздела: returnItemId

Данные:

------------------------------------
| id                | returnItemId |
------------------------------------
| "the_first_item"  | "123"        |
| "the_first_item"  | "456"        |
| "the_first_item"  | "789"        |
| "the_second_item" | "987"        |
| "the_second_item" | "654"        |
| "the_second_item" | "321"        |
------------------------------------

затем запросите GSI для ключевого условия returnItemId = 987 (без выражения фильтра)

...