DynamoDB, как сделать запрос с BEGINS_WITH
Я использую DocumentClient для запроса. и используя безсерверный фреймворк с DynamoDb.
Я пытаюсь сделать запрос с BEGINS_WITH без предоставления первичного ключа.
вот как выглядят мои данные:
[
{
id: 1,
some_string: "77281829121"
},
{
id: 2,
some_string: "7712162hgvh"
},
{
id: 3,
some_string: "7212121"
}
]
вот мой serverless.yml
[т.е. таблица конфигурации я думаю]:
Resources:
IPRecord:
Type: 'AWS::DynamoDB::Table'
Properties:
TableName: ${file(./serverless.js):Tables.IPRecord.name}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: 'id'
AttributeType: 'S'
- AttributeName: 'some_string'
AttributeType: 'S'
KeySchema:
- AttributeName: 'id'
KeyType: 'HASH'
GlobalSecondaryIndexes:
- IndexName: ${file(./serverless.js):Tables.IPRecord.index.ID}
KeySchema:
# ...some more index goes here
- AttributeName: 'some_string'
KeyType: 'RANGE'
Projection:
ProjectionType: 'ALL'
Q: Используя DocumentClinet, я хочу сделать запрос с первыми несколькими элементами some_string
, который вернет все документы, которые совпадают. как в этом случае я хочу запросить {some_string:"77"}
и он вернется
[{
id: 1,
some_string: "77281829121"
},
{
id: 2,
some_string: "7712162hgvh"
}]
в настоящее время мой запрос выглядит следующим образом [это дает ошибку] [Запуск в локальной оболочке DynamoDB JS]:
var params = {
TableName: '<TABLE_NAME>',
IndexName: '<INDEX_NAME>',
KeyConditionExpression: 'begins_with(some_string,:value)',
ExpressionAttributeValues: {
':value': '77'
}
};
docClient.query(params, function(err, data) {
if (err) ppJson(err);
else ppJson(data);
});
Кажется, что этот запрос требует первичного ключа, и в моем случае это id
, если я передам это, то это будет указывать на один документ.
Вот что я достиг на данный момент:
var params = {
TableName: '<TABLE_NAME>',
FilterExpression: 'begins_with(some_string,:value)',
ExpressionAttributeValues: {
':value': '77'
},
Select:'COUNT' //as i only required COUNT
};
docClient.scan(params, function(err, data) {
if (err) ppJson(err);
else ppJson(data);
});
этот запрос делает то, что я хочу. но всегда приветствуется любой лучший подход или решение.
1 ответ
Если количество символов в вашем запросе beginwith всегда будет случайным, я не вижу опции, решающей это с помощью dynamicodb.
но скажем, будет не менее 3 символов. тогда вы можете сделать следующее.
Обновите вашу схему DynamodB для
IPRecord:
Type: 'AWS::DynamoDB::Table'
Properties:
TableName: ${file(./serverless.js):Tables.IPRecord.name}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: 'id'
AttributeType: 'S'
- AttributeName: 'some_string'
AttributeType: 'S'
KeySchema:
- AttributeName: 'id'
KeyType: 'HASH'
- AttributeName: 'some_string'
KeyType: 'RANGE'
И вместо хранения
[
{
id: 1,
some_string: "77281829121"
},
{
id: 2,
some_string: "7712162hgvh"
},
{
id: 3,
some_string: "7212121"
}
]
хранить как
[
{
id: 772,
uniqueid:1,
some_string: "77281829121"
},
{
id: 771,
uniqueid:2,
some_string: "7712162hgvh"
},
{
id: 721,
uniqueid:3,
some_string: "7212121"
}
]
Где id - это всегда первые 3 символа оригинальной строки some_string.
Теперь предположим, что вам нужно запросить все элементы, которые начинаются с abcx
ты можешь сделать
select * where id=abc and some_string startswith abcx
но вы всегда должны стараться иметь большее количество символов в id, чтобы загрузка распределялась случайным образом. например, если есть только 2 символа, возможны только 36*36 идентификаторов, если есть 3 символа, 36*36*36 идентификаторов возможны.