clarkie / dynogels

DynamoDB data mapper for node.js. Originally forked from https://github.com/ryanfitz/vogels
Other
491 stars 110 forks source link

Cannot use "startKey" when using an index #184

Open mhconradt opened 5 years ago

mhconradt commented 5 years ago

Example query below: const { Items, LastEvaluatedKey } = await this.model. query(objectId). usingIndex('objectId-updatedAt-index'). startKey(objectId, startKey || "_"). limit(limit || 20). attributes(this.defaultAttributes). execAsync(); The generated request is here: { IndexName: 'objectId-updatedAt-index', ExclusiveStartKey: { objectId: 'alpha1_customer_1', noteId: '_' }, Limit: 20, ProjectionExpression: '#objectId,#noteId,#updatedAt,#message', ExpressionAttributeNames: { '#objectId': 'objectId', '#noteId': 'noteId', '#updatedAt': 'updatedAt', '#message': 'message' } } } It generates the following error: ValidationException: The provided starting key is invalid The problem is that the generated start key has the attributes objectId and noteId, when the index requires objectId and updatedAt. I am going to submit a PR for this shortly.

deedw commented 4 years ago

I also ran into this issue.

startKey() provides the value for ExclusiveStartKey in the DynamoDB api call. The only valid value for ExclusiveStartKey is the value returned as LastEvaluatedKey from the previous query or scan operation, so correct functionality can be restored by changing the following functions:

Query.prototype.startKey = function (key) {
  this.request.ExclusiveStartKey = key;
  return this;
};
Scan.prototype.startKey = function (key) {
  this.request.ExclusiveStartKey = key;

  return this;
};

Note that this would be a breaking change from existing startKey(hashKey, rangeKey) parameters.

I implemented a temporary fix in my application as follows:

const dynogels = require('dynogels');

require('dynogels/lib/query').prototype.startKey = function (key) {
    this.request.ExclusiveStartKey = key;

  return this;
};

require('dynogels/lib/scan').prototype.startKey = function (key) {
    this.request.ExclusiveStartKey = key;

  return this;
};