gadelkareem / sails-dynamodb

Amazon DynamoDB adapter for Waterline / Sails.js
http://sailsjs.org
46 stars 22 forks source link

added new method to make where queries consistent with mongodb adapter #23

Closed mattmccarty closed 8 years ago

mattmccarty commented 8 years ago

Use case example:

model.findOne().where({ and: [ { 'title': 'My Title' }, { 'tag': 'my-tag' } ] }.exec(function findCB(err, found) { // Do stuff });

mattmccarty commented 8 years ago

Just added support for Dynamo's 'ConditionalOperator' setting to allow OR conditions instead of just AND conditions

devinivy commented 8 years ago

Thanks! Looking through this.

mattmccarty commented 8 years ago

No problem. Let me know if you need me to explain anything.

Also, I just committed a change that fixes queries that have a Limit > 0 set. According to the AWS docs, if a limit on the number of records is set to something > 0, then the scan() function in aws-sdk will only scan the number of records set as the Limit value. It's up to the developer to create a loop to keep scanning te database until the end of the database table is reached or until the query returns results.

See: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelPHPScanning.html

I committed all of these changes in the same branch because they are fairly related.

devinivy commented 8 years ago

In your latest findOne fix– how do you tell that the results are being scanned? I mean, what happens here if an indexed find() query returns 0 results? Also, is findOne currently using a page size of 1 (the limit passed to the adapter) as we manually scan through the table?

mattmccarty commented 8 years ago

Sorry for the late reply. I've been quite busy this week.

To answer your first question, the code scans the same as it used to with find() unless dynamo returns a LastEvaluatedKey (returned with findOne or any other method that sets a LIMIT less than the actualy number of items in the table). If the LastEvaluatedKey property is set in the response, this means that not all of the items in the database have been scanned, so we need to keep scanning. The next scan will start on the row pointed to by LastEvaluatedKey. the Below is what returns with the find() method when no results are returned:

{ Items: [], Count: 0, ScannedCount: 4 }

The response above is exactly the response that we would have gotten without the committed chanages.

For your second question, findOne() does set the LIMIT to one and dynamo does in fact scan only one item. In other databases (mongo for example), when findOne() is executed, it will keep searching the collection until one item is found (that matches the search criteria) or will return with 0 results if it reaches the end of the collection without a match, therefore, there are clear differences in how dynamo scans a table and other databases scan their collections. Dynamo scans the first row then stops, so you have to keep iterating over the table and other databases keep scanning automatically until an item is found or the end of the collection is reached.

Hopefully that answers your questions.

mattmccarty commented 8 years ago

Any update on this?

devinivy commented 8 years ago

This looks good– thank you! I regret not having proper tests to run, as it would have made review much quicker. I appreciate you bearing with what turned out to be an insanely long review process. The adapter just got quite a bit better, so thanks again!

mattmccarty commented 8 years ago

No problem! Glad I could help.