4

I am using boto3 to query DynamoDB. And I have heard that table.query() is more efficient that table.scan() I was wondering if there is a way to check if the value exists using query() method?

response = table.scan(FilterExpression=Attr('attribute').exists()

If it is not possible to check using .query() is there any other method that is more efficient than .scan()?

This question is not a duplicate - I am looking for a way to optimize querying for existing/non existing attributes of .query() or .scan()

Barbara Gendron
  • 385
  • 1
  • 2
  • 16
BanzaiTokyo
  • 1,376
  • 4
  • 17
  • 33
  • Possible duplicate of [How do you query for a non-existent (null) attribute in DynamoDB](https://stackoverflow.com/questions/34349135/how-do-you-query-for-a-non-existent-null-attribute-in-dynamodb) – PseudoAj Jul 20 '17 at 21:01
  • @Chris Nauroth I don't think it is a duplicate as it talks about scan() and my question is about query() – BanzaiTokyo Jul 20 '17 at 22:57

2 Answers2

1

It seems that query() is more efficient than scan() because it works with hash key only, and the query must match base table schema. That is the reason for it to be so efficient.

Therefore it is not possible to scan() for attributes that are not in the base schema.

BanzaiTokyo
  • 1,376
  • 4
  • 17
  • 33
0

As it is said by @BanzaiTokyo, the query() method is more efficient than scan() because it simply does not search from top to bottom but instead it relies on PK and SK.

These documentation explain and shows very well the Boto3 functions using conditions on KeyConditions or FilterExpressions.

https://boto3.amazonaws.com/v1/documentation/api/latest/_modules/boto3/dynamodb/conditions.html

Therefore, to check if a value exists we should use the attribute_exists(path) function, where path is the attribute in your DynamoDB table.

response = table.query(
  FilterExpression: 'attribute_exists(USER)' #USER is the name of the attribute
)

Remember to specify the table name and the query can be combined with KeyConditionExpression to facilitate the search.

Alfred
  • 1
  • 1