Вы можете использовать FilterExpression или составные ключи сортировки.
FilterExpression
Здесь вы можете получить элементы из GSI, который вы описали, указав «serviceId» и «date», а затем указавв выражении FilterExpression, указывающем time.startTime и time.endTime. Пример кода Python с использованием boto3 будет выглядеть следующим образом:
response = table.query(
KeyConditionExpression=Key('serviceId').eq(1) & Key('date').eq("2019-10-05"),
FilterExpression=Attr(time.endTime).eq('1300') & Attr('time.startTime').eq('1330')
)
Недостаток этого метода заключается в том, что все элементы, указанные с помощью ключа сортировки, будут прочитаны, и только после этого результаты будут отфильтрованы. Таким образом, с вас будет взиматься плата в соответствии с указанным в ключе сортировки.
Например: если 1000 элементов имеют «serviceId» в качестве 1 и «date» в качестве «2019-10-05», но только 10 элементов имеют «time.startTime 'как 1330, тогда вы все равно будете платить за чтение 1000 элементов, даже если после применения FilterExpression будет возвращено только 10 элементов.
Ключ составной сортировки
Я считаю, что этоэто метод, который вы упомянули в вопросе. Здесь вам нужно сделать атрибут как
'yyyy-mm-dd_startTime_endTime'
и использовать его в качестве ключа сортировки в GSI. Теперь ваши элементы будут выглядеть так:
{ "date": "2019-10-05",
"id": "2",
"serviceId": "1",
"time": {
"endTime": "1300",
"startTime": "1330"
}
"date_time":"2019-10-05_1330_1300"
}
Ваш GSI будет иметь «serviceId» в качестве ключа раздела и «date_time» в качестве ключа сортировки. Теперь вы сможете запросить диапазон дат как:
response = table.query(
KeyConditionExpression=Key('serviceId').eq(1) & Key('date').between('2019-07-05','2019-10-05')
)
Для запроса, в котором указаны дата, время начала и окончания, вы можете запросить как:
response = table.query(
KeyConditionExpression=Key('serviceId').eq(1) & Key('date').eq('2019-10-05_1330_1300')
)
Этот подход выигралне работает, если вам нужен диапазон дат и время начала и окончания вместе, т.е. Вы не сможете сделать запрос для элементов в определенном диапазоне дат, содержащих определенное время начала и окончания. В этом случае вам придется использовать FilterExpression.