AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2025-06-07 · Documentation low

File: code-library/latest/ug/javascript_3_dynamodb_code_examples.md

Summary

Added code example demonstrating comparison of multiple values using IN operator in DynamoDB queries

Security assessment

The change adds documentation about query optimization techniques using the IN operator without any security implications.

Diff

diff --git a/code-library/latest/ug/javascript_3_dynamodb_code_examples.md b/code-library/latest/ug/javascript_3_dynamodb_code_examples.md
index 9ba23d1b4..9f05bcf54 100644
--- a//code-library/latest/ug/javascript_3_dynamodb_code_examples.md
+++ b//code-library/latest/ug/javascript_3_dynamodb_code_examples.md
@@ -1305,0 +1306,337 @@ This example is also available in the [AWS SDK for JavaScript v3 developer guide
+The following code example shows how to compare multiple values with a single attribute in DynamoDB.
+
+  * Use the IN operator to compare multiple values with a single attribute.
+
+  * Compare the IN operator with multiple OR conditions.
+
+  * Understand the performance and expression complexity benefits of using IN.
+
+
+
+
+**SDK for JavaScript (v3)**
+    
+
+Compare multiple values with a single attribute using AWS SDK for JavaScript.
+    
+    
+    const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
+    const { 
+      DynamoDBDocumentClient, 
+      ScanCommand, 
+      QueryCommand 
+    } = require("@aws-sdk/lib-dynamodb");
+    
+    /**
+     * Query or scan a DynamoDB table to find items where an attribute matches any value from a list.
+     * 
+     * This function demonstrates the use of the IN operator to compare a single attribute
+     * against multiple possible values, which is more efficient than using multiple OR conditions.
+     * 
+     * @param {Object} config - AWS configuration object
+     * @param {string} tableName - The name of the DynamoDB table
+     * @param {string} attributeName - The name of the attribute to compare against the values list
+     * @param {Array} valuesList - List of values to compare the attribute against
+     * @param {string} [partitionKeyName] - Optional name of the partition key attribute for query operations
+     * @param {string} [partitionKeyValue] - Optional value of the partition key to query
+     * @returns {Promise<Object>} - The response from DynamoDB containing the matching items
+     */
+    async function compareMultipleValues(
+      config,
+      tableName,
+      attributeName,
+      valuesList,
+      partitionKeyName,
+      partitionKeyValue
+    ) {
+      // Initialize the DynamoDB client
+      const client = new DynamoDBClient(config);
+      const docClient = DynamoDBDocumentClient.from(client);
+      
+      // Create the filter expression using the IN operator
+      const filterExpression = `${attributeName} IN (${valuesList.map((_, index) => `:val${index}`).join(', ')})`;
+      
+      // Create expression attribute values for the values list
+      const expressionAttributeValues = valuesList.reduce((acc, val, index) => {
+        acc[`:val${index}`] = val;
+        return acc;
+      }, {});
+      
+      // If partition key is provided, perform a query operation
+      if (partitionKeyName && partitionKeyValue) {
+        const keyCondition = `${partitionKeyName} = :partitionKey`;
+        expressionAttributeValues[':partitionKey'] = partitionKeyValue;
+        
+        // Initialize array to collect all items
+        let allItems = [];
+        let lastEvaluatedKey;
+        
+        // Use pagination to get all results
+        do {
+          const params = {
+            TableName: tableName,
+            KeyConditionExpression: keyCondition,
+            FilterExpression: filterExpression,
+            ExpressionAttributeValues: expressionAttributeValues
+          };
+          
+          // Add ExclusiveStartKey if we have a lastEvaluatedKey from a previous query
+          if (lastEvaluatedKey) {
+            params.ExclusiveStartKey = lastEvaluatedKey;
+          }
+          
+          const response = await docClient.send(new QueryCommand(params));
+          
+          // Add the items from this page to our collection
+          if (response.Items && response.Items.length > 0) {
+            allItems = [...allItems, ...response.Items];
+          }
+          
+          // Get the key for the next page of results
+          lastEvaluatedKey = response.LastEvaluatedKey;
+        } while (lastEvaluatedKey);
+        
+        // Return the complete result
+        return {
+          Items: allItems,
+          Count: allItems.length
+        };
+      } else {
+        // Otherwise, perform a scan operation
+        // Initialize array to collect all items
+        let allItems = [];
+        let lastEvaluatedKey;
+        
+        // Use pagination to get all results
+        do {
+          const params = {
+            TableName: tableName,
+            FilterExpression: filterExpression,
+            ExpressionAttributeValues: expressionAttributeValues
+          };
+          
+          // Add ExclusiveStartKey if we have a lastEvaluatedKey from a previous scan
+          if (lastEvaluatedKey) {
+            params.ExclusiveStartKey = lastEvaluatedKey;
+          }
+          
+          const response = await docClient.send(new ScanCommand(params));
+          
+          // Add the items from this page to our collection
+          if (response.Items && response.Items.length > 0) {
+            allItems = [...allItems, ...response.Items];
+          }
+          
+          // Get the key for the next page of results
+          lastEvaluatedKey = response.LastEvaluatedKey;
+        } while (lastEvaluatedKey);
+        
+        // Return the complete result
+        return {
+          Items: allItems,
+          Count: allItems.length
+        };
+      }
+    }
+    
+    /**
+     * Alternative implementation using multiple OR conditions instead of the IN operator.
+     * 
+     * This function is provided for comparison to show why using the IN operator is preferable.
+     * With many values, this approach becomes verbose and less efficient.
+     * 
+     * @param {Object} config - AWS configuration object
+     * @param {string} tableName - The name of the DynamoDB table
+     * @param {string} attributeName - The name of the attribute to compare against the values list
+     * @param {Array} valuesList - List of values to compare the attribute against
+     * @param {string} [partitionKeyName] - Optional name of the partition key attribute for query operations
+     * @param {string} [partitionKeyValue] - Optional value of the partition key to query
+     * @returns {Promise<Object>} - The response from DynamoDB containing the matching items
+     */
+    async function compareWithOrConditions(
+      config,
+      tableName,
+      attributeName,
+      valuesList,
+      partitionKeyName,
+      partitionKeyValue
+    ) {
+      // Initialize the DynamoDB client
+      const client = new DynamoDBClient(config);
+      const docClient = DynamoDBDocumentClient.from(client);
+      
+      // If no values provided, return empty result
+      if (!valuesList || valuesList.length === 0) {
+        return {
+          Items: [],
+          Count: 0
+        };
+      }
+      
+      // Create the filter expression using multiple OR conditions
+      const filterConditions = valuesList.map((_, index) => `${attributeName} = :val${index}`);
+      const filterExpression = filterConditions.join(' OR ');
+      
+      // Create expression attribute values for the values list
+      const expressionAttributeValues = valuesList.reduce((acc, val, index) => {
+        acc[`:val${index}`] = val;
+        return acc;
+      }, {});
+      
+      // If partition key is provided, perform a query operation
+      if (partitionKeyName && partitionKeyValue) {
+        const keyCondition = `${partitionKeyName} = :partitionKey`;
+        expressionAttributeValues[':partitionKey'] = partitionKeyValue;
+        
+        // Initialize array to collect all items
+        let allItems = [];
+        let lastEvaluatedKey;
+        
+        // Use pagination to get all results
+        do {
+          const params = {
+            TableName: tableName,
+            KeyConditionExpression: keyCondition,
+            FilterExpression: filterExpression,