开始日期结束日期范围查询的Dynamodb模型数据
Dynamodb Model data for Start Date End Date range query
我的问题可能类似于以下问题
How to query for an entry that falls between start and end date - DynamoDB
但我认为在我的要求和我正在寻找的方面是不同的。
对于特定的分区键值,我想查询当前日期介于开始日期和结束日期之间的所有记录。
我的用例是创建调查。每个调查都有一个名称并属于一个类别。每个调查都有一个开始日期和结束日期。我需要查询给定类别的所有活动调查的名称,即当前日期介于开始日期和结束日期之间的类别的所有调查。此外,调查可以是 Active/Inactive.
目前做了什么:
Table 设计:table tbl_surveys
分区键:tbl_pk_surv
排序 Key:tbl_sk_surv
一个"Data"属性:data_attr
我创建了一个 GSI,其中 tbl_sk_surv 作为分区键 ,data_attr 作为排序键.
我正在为每个调查创建 2 条记录:
tbl_pk_surv|tbl_sk_surv|data_attr|cat_name|start_date|end_date|状态
生存-0tOrClRnTz|调查 |调查 1 | Cat1 |1564012800|1564876799|1<br>
tbl_pk_surv | tbl_sk_surv | data_attr| survey_name |状态
生存-0tOrClRnTz |类别 1 | 1564012800-1564876799 |调查 1 | 1<br>
所以我将开始日期和结束日期放在第二条记录的 1 列中。我的计划是,我想查询 GSI 分区键值 "Cat1",并获取 "Cat1" 的所有调查名称。请告诉我如何查询GSI排序键值1564012800-1564876799,以便我可以在开始日期到结束日期之间进行查询。
请注意,我将第一条记录的静态值 "SURVEY" 作为 pk_sk_surv 属性的值,这样我就可以通过使用 [=56 查询 GSI 来查询所有调查记录=] 作为分区键值。我正在尝试实现单table no-sql 设计。
我是 NoSql Design 的新手,请指导我如何建模数据和查询我的需求。
如果我理解正确的话,你的记录会有开始日期和结束日期(即你有一个时间间隔)并且你想要查询 return 跨越特定值的记录(即. start date is less than input value and end date is greater than input value)那么答案是DynamoDB不直接支持这种类型的查询。我的意思是你必须在查询之上应用过滤器。过滤仍然由 Dynamo 完成,但它将在执行查询之后和结果 returned 之前完成。
在最一般的情况下,对于任意时间,您可以编写一个查询来获取在查询时间之前开始的所有调查,并过滤掉也在查询时间之前结束的不需要的调查。
但是您的情况是一个特例,因为大概大多数调查会在查询时间之前开始和结束,因此在当前时间之后结束的唯一可能不需要的结果将是已安排但尚未开始的调查。在这种情况下,您将编写查询以获取结束日期在查询时间之后的所有调查,并过滤掉任何不需要的调查,这些调查应该不会那么多。
如果您知道一项调查可以 运行 的最长时间(比如 1 个月),您可以通过设置结束日期的上限来进一步优化此查询。然后,您可以查询在查询日期和查询日期 + 上限之间结束的所有调查,然后应用过滤器。它仍然需要过滤掉一些结果,但取决于您的上限有多紧,它可能非常有效。
要实现这一点,您需要将分区键设置为 "category" 属性并将排序键设置为 "endDate",并使用单独的属性 "startDate" 来表示开始日期。
查询将如下所示(Javascript 中的示例):
// assume the following are your input variable
var search_category = 'some category name';
var current_time = new Date().getTime() / 1000; // current time epoch
var max_time = current_time + 3600 * 24 * 31; // set upper bound to +1 month
var docClient = new AWS.DynamoDB.DocumentClient();
var result = await docClient.query({
TableName : "SurveysTable",
KeyConditionExpression: "#cat = :cat and #end between :ltime and :htime",
FilterExpression: "#start < :ltime",
ExpressionAttributeNames:{
"#cat": "category",
"#start": "startDate",
"#end": "endDate"
},
ExpressionAttributeValues: {
":cat": search_category,
":ltime": current_time,
":htime": max_time
}
}).promise();
// don't forget to handle pagination
我的问题可能类似于以下问题
How to query for an entry that falls between start and end date - DynamoDB
但我认为在我的要求和我正在寻找的方面是不同的。
对于特定的分区键值,我想查询当前日期介于开始日期和结束日期之间的所有记录。
我的用例是创建调查。每个调查都有一个名称并属于一个类别。每个调查都有一个开始日期和结束日期。我需要查询给定类别的所有活动调查的名称,即当前日期介于开始日期和结束日期之间的类别的所有调查。此外,调查可以是 Active/Inactive.
目前做了什么:
Table 设计:table tbl_surveys
分区键:tbl_pk_surv
排序 Key:tbl_sk_surv
一个"Data"属性:data_attr
我创建了一个 GSI,其中 tbl_sk_surv 作为分区键 ,data_attr 作为排序键.
我正在为每个调查创建 2 条记录:
tbl_pk_surv|tbl_sk_surv|data_attr|cat_name|start_date|end_date|状态
生存-0tOrClRnTz|调查 |调查 1 | Cat1 |1564012800|1564876799|1<br>
tbl_pk_surv | tbl_sk_surv | data_attr| survey_name |状态
生存-0tOrClRnTz |类别 1 | 1564012800-1564876799 |调查 1 | 1<br>
所以我将开始日期和结束日期放在第二条记录的 1 列中。我的计划是,我想查询 GSI 分区键值 "Cat1",并获取 "Cat1" 的所有调查名称。请告诉我如何查询GSI排序键值1564012800-1564876799,以便我可以在开始日期到结束日期之间进行查询。
请注意,我将第一条记录的静态值 "SURVEY" 作为 pk_sk_surv 属性的值,这样我就可以通过使用 [=56 查询 GSI 来查询所有调查记录=] 作为分区键值。我正在尝试实现单table no-sql 设计。
我是 NoSql Design 的新手,请指导我如何建模数据和查询我的需求。
如果我理解正确的话,你的记录会有开始日期和结束日期(即你有一个时间间隔)并且你想要查询 return 跨越特定值的记录(即. start date is less than input value and end date is greater than input value)那么答案是DynamoDB不直接支持这种类型的查询。我的意思是你必须在查询之上应用过滤器。过滤仍然由 Dynamo 完成,但它将在执行查询之后和结果 returned 之前完成。
在最一般的情况下,对于任意时间,您可以编写一个查询来获取在查询时间之前开始的所有调查,并过滤掉也在查询时间之前结束的不需要的调查。
但是您的情况是一个特例,因为大概大多数调查会在查询时间之前开始和结束,因此在当前时间之后结束的唯一可能不需要的结果将是已安排但尚未开始的调查。在这种情况下,您将编写查询以获取结束日期在查询时间之后的所有调查,并过滤掉任何不需要的调查,这些调查应该不会那么多。
如果您知道一项调查可以 运行 的最长时间(比如 1 个月),您可以通过设置结束日期的上限来进一步优化此查询。然后,您可以查询在查询日期和查询日期 + 上限之间结束的所有调查,然后应用过滤器。它仍然需要过滤掉一些结果,但取决于您的上限有多紧,它可能非常有效。
要实现这一点,您需要将分区键设置为 "category" 属性并将排序键设置为 "endDate",并使用单独的属性 "startDate" 来表示开始日期。
查询将如下所示(Javascript 中的示例):
// assume the following are your input variable
var search_category = 'some category name';
var current_time = new Date().getTime() / 1000; // current time epoch
var max_time = current_time + 3600 * 24 * 31; // set upper bound to +1 month
var docClient = new AWS.DynamoDB.DocumentClient();
var result = await docClient.query({
TableName : "SurveysTable",
KeyConditionExpression: "#cat = :cat and #end between :ltime and :htime",
FilterExpression: "#start < :ltime",
ExpressionAttributeNames:{
"#cat": "category",
"#start": "startDate",
"#end": "endDate"
},
ExpressionAttributeValues: {
":cat": search_category,
":ltime": current_time,
":htime": max_time
}
}).promise();
// don't forget to handle pagination