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

Я имею 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
});

Эти два элемента выглядят как

Я пытаюсь выполнить запрос и получить правильный элемент, который содержит 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
});

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

1 ответ

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 (без выражения фильтра)

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