Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB FilterExpression with NOT IN

I'm trying to run a filter expression on a DynamoDB query (in a Node.JS environment), for one of the attributes not to be in a list of those attributes. I'm doing this:

documentClient.query( {
    TableName: 'event',
    IndexName: 'OrganisationTimestamp',
    KeyConditionExpression: '#ts BETWEEN :from AND :to',
    ExpressionAttributeNames: {
      '#ts': 'Timestamp'
    },
    ExpressionAttributeValues: {
        ':to': to,
        ':from': from,
        ':ignoredUserIds': "1, 2, 3"
    },
    FilterExpression: 'not (userId in (:ignoredUserIds))'
  })

However I'm not having any luck here, and getting items back with the userId attribute within that range.

Any help much appreciated, thanks!

like image 570
Joseph Paterson Avatar asked Jan 23 '17 23:01

Joseph Paterson


People also ask

Does DynamoDB Scan return all items?

A Scan operation in Amazon DynamoDB reads every item in a table or a secondary index. By default, a Scan operation returns all of the data attributes for every item in the table or index. You can use the ProjectionExpression parameter so that Scan only returns some of the attributes, rather than all of them.

Can you Query on sort key?

You can Query any table or secondary index, provided that it has a composite primary key (partition key and sort key).

Can you Query without sort key DynamoDB?

Hash key in DynamoDB The primary reason for that complexity is that you cannot query DynamoDB without the hash key. So, it's not allowed to query the entire database. That means you cannot do what you would call a full table scan in other databases.

IS NOT NULL DynamoDB?

There is no NotNull constraint explicitly available on DynamoDB. However there is a feature to provide default value for the attribute if you are using DynamoDBMapper. Also, DynamoDB API doesn't allow to add an attribute with empty value (i.e. Null or empty string '').


2 Answers

IN - can be used only if userId attribute is defined as DynamoDB LIST data type

IN : Checks for matching elements in a list.

AttributeValueList can contain one or more AttributeValue elements of type String, Number, or Binary. These attributes are compared against an existing attribute of an item. If any elements of the input are equal to the item attribute, the expression evaluates to true.

Solution:

Change the FilterExpression and ExpressionAttributeValues as mentioned below. It should work.

ExpressionAttributeValues: {
        ':to': to,
        ':from': from,
        ':userid1': "1",
        ':userid2': "2",
        ':userid3': "3"        
    },
FilterExpression: 'userId <> :userid1 and userId <> :userid2 and userId <> :userid3'
like image 87
notionquest Avatar answered Sep 30 '22 17:09

notionquest


You're using ignoredUserIds as if it was a Macro... you should do:

ExpressionAttributeValues: {
    ':to': to,
    ':from': from,
    ':id1': 1,
    ':id2': 2,
    ':id3': 3,
},
FilterExpression: 'not (userId in (:id1, :id2, id3))'

if you're only mapping numbers you should be able to do:

FilterExpression: 'not (userId in (1, 2, 3))'
like image 42
Xeltor Avatar answered Sep 30 '22 17:09

Xeltor