How to use “IN” statement in FilterExpression using array - dynamodb

前端 未结 6 2047
猫巷女王i
猫巷女王i 2020-12-08 15:58

Checked AWS document but did not find any working example.

Here is my attempt

var params = {
            TableName: \"User\",
            IndexName:\         


        
相关标签:
6条回答
  • 2020-12-08 16:10

    Please refer this answer

    Summary:-

    For fixed number of values in "IN" clause:-

    var params = {
        TableName : "Users",
        FilterExpression : "username IN (:user1, :user2)",
        ExpressionAttributeValues : {
            ":user1" : "john",
            ":user2" : "mike"
        }
    };
    

    For more elements in array and forming the FilterExpression dynamically:-

    var titleValues = ["The Big New Movie 2012", "The Big New Movie"];
    var titleObject = {};
    var index = 0;
    titleValues.forEach(function(value) {
        index++;
        var titleKey = ":titlevalue"+index;
        titleObject[titleKey.toString()] = value;
    });
    
    var params = {
        TableName : "Movies",
        FilterExpression : "title IN ("+Object.keys(titleObject).toString()+ ")",
        ExpressionAttributeValues : titleObject
    };
    
    0 讨论(0)
  • 2020-12-08 16:10

    Using es5 and map:

    const params = {
      TableName: 'personalizations',
      KeyConditionExpression: 'accountId = :accountId',
      FilterExpression: `websiteId IN (${websites.map(w => `:${w.websiteId}`).join(',')})`,
      ExpressionAttributeValues: {':accountId': accountId}
    }
    for (const website of websites) {
      params.ExpressionAttributeValues[`:${website.websiteId}`] = website.websiteId
    }
    
    const {Items: personalizations} = await docClient.query(params).promise()
    
    0 讨论(0)
  • 2020-12-08 16:20

    notionquest's answer is correct but i cant use my other values in ExpressionAttributeValues like :country and :status so here is modified answer to make it working as per my requirements

    var AttributeValuesObject = {};
    
      AttributeValuesObject[':country '] = "USA";
      AttributeValuesObject[':status'] = 1;
    
      var titleValues = ["1", "2"];
      var titleObject = {}; 
    
      var index = 0; 
    
      titleValues.forEach(function(value) {
        index++;
        var titleKey = ":titleValue"+index;
        AttributeValuesObject[titleKey.toString()] = value;
        titleObject[titleKey.toString()] = value;
      });
    
      var params = {
        TableName: "User",
        IndexName:"a-b-index",
        KeyConditionExpression: "Country = :country and #s = :status",
        FilterExpression: "Id IN ("+Object.keys(titleObject).toString()+ ")",
        ExpressionAttributeValues: AttributeValuesObject,
        ExpressionAttributeNames: {"#s": "Status"}
      };
    
      //get users
      dynamodb.query(params, function (err, data) {
        if (err)
          //error
        else {
          //success
    
        }
       });
    
    0 讨论(0)
  • 2020-12-08 16:21

    The Python3 version:

    def get_filter_for_in_clause(column_name, in_values, column_type="S"):
        expressions = []
        for i in range(len(in_values)):
            expressions.append(f':temp{i}')
        filter_expression = f'{column_name} IN ({", ".join(expressions)})'
    
        expression_attribute_values = {}
        for index, expression in enumerate(expressions):
            expression_attribute_values[expression] = {column_type: in_values[index]}
    
        return filter_expression, expression_attribute_values
    

    Usage:

    column = 'testcolumn'
    inputs = ['testvalue1', 'testvalue2', 'testvalue3']
    filter_expression, expression_attribute_values = get_filter_for_in_clause(column, inputs)
    

    Result:

    # filter_expression = 'testcolumn IN (:temp0, :temp1, :temp2)'
    # expression_attribute_values = {':temp0': {'S': 'testvalue1'}, ':temp1': {'S': 'testvalue2'}, ':temp2': {'S': 'testvalue3'}}
    
    0 讨论(0)
  • 2020-12-08 16:25

    You could also use notionquest's approach and simply insert your other attribute values inside the titleObject{}. e.g.

    var titleObject = { ": country": "USA", ":status": 1, }; 
    

    Note: You might have to add schema like "S" if you're not using DocumentClient

         var titleObject = { 
          ":country": { "S":"USA" }, ...
    
    }
    
    0 讨论(0)
  • 2020-12-08 16:26

    I've done it like this, parsing the params list once

    const users = [{userId:1, name:'joe'}, {userId:2, name:'mike'}]
    const expressionAttributeValues = {};
    const userIdParams = users.map((u, i) => {
      const userParam = `:user${i}`;
      expressionAttributeValues[userParam] = u.userId;
      return userParam;
    }).join(',')
    var params = {
        TableName : 'Users',
        FilterExpression : `username IN (${userIdParams})`,
        ExpressionAttributeValues : expressionAttributeValues
    };

    0 讨论(0)
提交回复
热议问题