如何查询:过滤多个主分区键和主排序键上的范围

时间:2016-06-06 14:38:31

标签: amazon-web-services amazon-dynamodb

背景 我有一个dynamoDB表,包括主分区键clientID(“N”)和主要排序键createdAt(“S”)(作为UTC ISO 8601日期)+一些其他属性。

问题 我想向后查询createdAt BETWEEN两个日期的所有项目,一次仅查询大约100个特定clientID个项目。

  • 死胡同1:首先我考虑使用BatchGetItem,但是虽然我知道我要查询的clientID是什么,但我无法指定排序键,因为我我正在寻找在一段时间内发生的事情。
  • 死胡同2 :其次我虽然关于使用Query,但是我不允许我同时寻找多个clientID(在看过'IN'运算符,but that one does not do what I was hoping for)。换句话说,如何在不必为时间范围内的每个Query ClientIDangular.module('web') .directive('alertSettingsPanel', function (config, $window, moment, $timeout, $http, SimpleModal) { 'use strict'; return { restrict: 'E', scope: { filter: '=alertSettingsPanel', department: '=' }, templateUrl: config.moduleRoots['web'] + '/AlertSettings/templates/partial.alertSettingsPanel.min.html', link: { pre: function (scope) { console.dir(scope); //initialize save text scope.saved = "Save Filter"; scope.validate = false; // Collapse the body if not new scope.UICollapseBody = scope.filter.id === 'new'; scope.UIBodyExpanded = scope.UICollapseBody; /** * Toggles the display of the body */ scope.UIToggleBody = function () { var nextCollapse = !scope.UICollapseBody; scope.UICollapseBody = nextCollapse; $timeout(function () { scope.UIBodyExpanded = nextCollapse; }, 300); }; //sends filter data to API for saving scope.save = function(){ scope.saved = "Saving..."; if(scope.filter.id === 'new'){ $http.post(config.apiBase + 'users/me/shifts/' + scope.$parent.shifts[scope.$parent.selectedShiftIndex].id + '/filters', { sendFollowup: scope.filter.sendFollowup, alert: {fileName: "default", type: scope.filter.alert.type}, type: scope.filter.type, description: scope.filter.description, priority: scope.filter.priority, value: scope.filter.value }).then(function(response){ scope.filter.id = response.data.id; scope.saved = "Saved!"; }, function(){ scope.saved = "Error saving"; }); } else{ $http.put(config.apiBase + 'users/me/shifts/' + scope.$parent.shifts[scope.$parent.selectedShiftIndex].id + '/filters/' + scope.filter.id, { sendFollowup: scope.filter.sendFollowup, alert: {filename: scope.filter.alert.filename, type: scope.filter.alert.type}, type: scope.filter.type, description: scope.filter.description, priority: scope.filter.priority, value: scope.filter.value }).success(function(){ scope.saved = "Saved!"; }).error(function(){ scope.saved = "Error saving"; }); } }; //Removes filter from local array //Note: Only use when the filter no longer exists on the server scope.uncreate = function() { scope.$parent.uncreateFilter(scope.$parent.filters.indexOf(scope.filter)); }; //Removes filter from shift in API scope.remove = function() { SimpleModal.open({ title: 'Remove filter?', body: 'Are you sure you want to remove this filter from your department?', type: 'confirm', buttons: { ok: 'Yes, remove this filter', cancel: 'Cancel' } }).then(function() { //REMOVE FROM SERVER $http.delete(config.apiBase + 'users/me/shifts/' + scope.$parent.shifts[scope.$parent.selectedShiftIndex].id + '/filters/' + scope.filter.id) .then( //remove locally scope.uncreate() ); }); }; } } }; }); 的情况下实现这一目标?

2 个答案:

答案 0 :(得分:1)

您提到的两个选项实际上是您唯一拥有的选项。

  • 选项1:将BatchGetItem用于所需的clientID,然后对createdAt执行应用程序端过滤。
  • 选项2:针对每个clientIDcreatedAt范围触发1个查询,然后在应用程序端合并数据。

您需要从两者中选择一种,具体取决于您的访问模式,表格结构和成本因素。

例如,如果createdAtclientID的平均数量不高,则选项1就足够了,因为它在读取容量单位上也是节俭的。

编辑:正如Niels在本回答的评论中指出的那样,选项1在这种特定情况下无法工作,因为BatchGetItem需要分区和排序键。

答案 1 :(得分:0)

我最后做了别的事情:

我添加了一个名为index_date的新属性,该属性仅包含created_at的日期部分(不是时间)。然后我在此属性上添加了一个新的辅助全局索引,其中created_at作为排序键。通过这种方式,我可以一次有效地查询一天中的所有项目(如果需要,可以在特定的时间范围内)。然后处理它们。