Запросить глобальный вторичный индекс, используя содержащийся в 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 (без выражения фильтра)