Tanaki
Tanaki

Reputation: 2635

Filtering / Querying by the Contents of a List in DynamoDB

I am attempting to filter a DynamoDB query by the contents of a Map contained within a List. Here's an example of the structure I'm dealing with.

{
    'EventType': 'git/push'
    'EventTime': 1416251010,
    'Commits': [
        {
            'id': '29d02aff...',
            'subject': 'Add the thing to the place'
        },
        {
            'id': '9d888fec...',
            'subject': 'Spelling errors'
        },
        ...
    ]
}

The hash key is EventType and range key EventTime. I am trying to write a filter that filters the result of a query to a specific id. Is is possible to create a DynamoDB filter expression that correctly filters the query like this? (My first thought was to use contains (a, a), but I don't think that will work on a List of Maps.)

Upvotes: 12

Views: 16863

Answers (2)

hcurnor
hcurnor

Reputation: 43

I found a solution and I tested it, and it is working fine. Here's what I did,

// created a schema like that:

var Movie = dynamo.define('example-nested-attribute', {
  hashKey : 'title',
  timestamps : true,
  schema : {
    title       : Joi.string(),
    releaseYear : Joi.number(),
    tags        : dynamo.types.stringSet(),
    director    : Joi.object().keys({
      firstName : Joi.string(),
      lastName  : Joi.string(),
      titles    : Joi.array()
    }),
    actors : Joi.array().items(Joi.object().keys({
      firstName : Joi.string(),
      lastName  : Joi.string(),
      titles    : Joi.array()
    }))
  }
});

and then you can query of a nested array of objects:

  var params = {};
  params.UpdateExpression = 'SET #year = #year + :inc, #dir.titles = list_append(#dir.titles, :title), #act[0].firstName = :firstName ADD tags :tag';
  params.ConditionExpression = '#year = :current';
  params.ExpressionAttributeNames = {
    '#year' : 'releaseYear',
    '#dir' : 'director',
    '#act' : 'actors'
  };
  params.ExpressionAttributeValues = {
    ':inc' : 1,
    ':current' : 2001,
    ':title' : ['The Man'],
    ':firstName' : 'Rob',
    ':tag' : dynamo.Set(['Sports', 'Horror'], 'S')
  };

Upvotes: 1

Johnny Wu
Johnny Wu

Reputation: 862

This isn't currently supported by DynamoDB's API's expression language (as of November 2014) but there are some workarounds mentioned here.

Upvotes: 6

Related Questions