View a markdown version of this page

使用 AWS SDK 查詢具有動態篩選條件表達式的 DynamoDB 資料表 - AWS SDK 程式碼範例

文件 AWS 開發套件範例 GitHub 儲存庫中有更多可用的 AWS SDK 範例

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 AWS SDK 查詢具有動態篩選條件表達式的 DynamoDB 資料表

下列程式碼範例示範如何使用動態篩選條件表達式查詢資料表。

  • 在執行時期動態建置篩選條件表達式。

  • 根據使用者輸入或應用程式狀態建構篩選條件。

  • 依條件新增或移除篩選條件。

Java
適用於 Java 2.x 的 SDK

使用 查詢具有動態建構篩選條件表達式的 DynamoDB 資料表 AWS SDK for Java 2.x。

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; import software.amazon.awssdk.services.dynamodb.model.QueryRequest; import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; import java.util.HashMap; import java.util.Map; public static QueryResponse queryWithDynamicFilter( final String tableName, final String partitionKeyName, final String partitionKeyValue, final Map<String, Object> filterCriteria, final Region region, final DynamoDbClient dynamoDbClient) { validateParameters(tableName, partitionKeyName, partitionKeyValue, filterCriteria); DynamoDbClient ddbClient = dynamoDbClient; boolean shouldClose = false; try { if (ddbClient == null) { ddbClient = createClient(region); shouldClose = true; } final QueryWithDynamicFilter queryHelper = new QueryWithDynamicFilter(ddbClient); return queryHelper.queryWithDynamicFilter(tableName, partitionKeyName, partitionKeyValue, filterCriteria); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); throw e; } catch (DynamoDbException e) { System.err.println("Failed to execute dynamic filter query: " + e.getMessage()); throw e; } catch (Exception e) { System.err.println("Unexpected error during query: " + e.getMessage()); throw e; } finally { if (shouldClose && ddbClient != null) { ddbClient.close(); } } }

示範如何使用動態篩選條件表達式 AWS SDK for Java 2.x。

public static void main(String[] args) { final String usage = """ Usage: <tableName> <partitionKeyName> <partitionKeyValue> <filterAttrName> <filterAttrValue> [region] Where: tableName - The Amazon DynamoDB table to query. partitionKeyName - The name of the partition key attribute. partitionKeyValue - The value of the partition key to query. filterAttrName - The name of the attribute to filter on. filterAttrValue - The value to filter by. region (optional) - The AWS region where the table exists. (Default: us-east-1) """; if (args.length < 5) { System.out.println(usage); System.exit(1); } final String tableName = args[0]; final String partitionKeyName = args[1]; final String partitionKeyValue = args[2]; final String filterAttrName = args[3]; final String filterAttrValue = args[4]; final Region region = args.length > 5 ? Region.of(args[5]) : Region.US_EAST_1; System.out.println("Querying items with dynamic filter: " + filterAttrName + " = " + filterAttrValue); try { // Using the builder pattern to create and execute the query final QueryResponse response = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriterion(filterAttrName, filterAttrValue) .withRegion(region) .execute(); // Process the results System.out.println("Found " + response.count() + " items:"); response.items().forEach(item -> System.out.println(item)); // Demonstrate multiple filter criteria System.out.println("\nNow querying with multiple filter criteria:"); Map<String, Object> multipleFilters = new HashMap<>(); multipleFilters.put(filterAttrName, filterAttrValue); multipleFilters.put("status", "active"); final QueryResponse multiFilterResponse = new DynamicFilterQueryBuilder() .withTableName(tableName) .withPartitionKeyName(partitionKeyName) .withPartitionKeyValue(partitionKeyValue) .withFilterCriteria(multipleFilters) .withRegion(region) .execute(); System.out.println("Found " + multiFilterResponse.count() + " items with multiple filters:"); multiFilterResponse.items().forEach(item -> System.out.println(item)); } catch (IllegalArgumentException e) { System.err.println("Invalid input: " + e.getMessage()); System.exit(1); } catch (ResourceNotFoundException e) { System.err.println("Table not found: " + tableName); System.exit(1); } catch (DynamoDbException e) { System.err.println("DynamoDB error: " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); System.exit(1); } }
  • 如需 API 的詳細資訊,請參閱《AWS SDK for Java 2.x API 參考》中的 Query

JavaScript
適用於 JavaScript (v3) 的 SDK

使用 查詢具有動態建構篩選條件表達式的 DynamoDB 資料表 AWS SDK for JavaScript。

const { DynamoDBClient, QueryCommand } = require("@aws-sdk/client-dynamodb"); async function queryWithDynamicFilter( config, tableName, partitionKeyName, partitionKeyValue, sortKeyName, sortKeyValue, filterParams = {} ) { try { // Create DynamoDB client const client = new DynamoDBClient(config); // Initialize filter expression components let filterExpressions = []; const expressionAttributeValues = { ":pkValue": { S: partitionKeyValue }, ":skValue": { S: sortKeyValue } }; const expressionAttributeNames = { "#pk": partitionKeyName, "#sk": sortKeyName }; // Add status filter if provided if (filterParams.status) { filterExpressions.push("status = :status"); expressionAttributeValues[":status"] = { S: filterParams.status }; } // Add minimum views filter if provided if (filterParams.minViews !== undefined) { filterExpressions.push("views >= :minViews"); expressionAttributeValues[":minViews"] = { N: filterParams.minViews.toString() }; } // Add author filter if provided if (filterParams.author) { filterExpressions.push("author = :author"); expressionAttributeValues[":author"] = { S: filterParams.author }; } // Construct the query input const input = { TableName: tableName, KeyConditionExpression: "#pk = :pkValue AND #sk = :skValue" }; // Add filter expression if any filters were provided if (filterExpressions.length > 0) { input.FilterExpression = filterExpressions.join(" AND "); } // Add expression attribute names and values input.ExpressionAttributeNames = expressionAttributeNames; input.ExpressionAttributeValues = expressionAttributeValues; // Execute the query const command = new QueryCommand(input); return await client.send(command); } catch (error) { console.error(`Error querying with dynamic filter: ${error}`); throw error; } }
  • 如需 API 的詳細資訊,請參閱《AWS SDK for JavaScript API 參考》中的 Query

Python
適用於 Python 的 SDK (Boto3)

使用 查詢具有動態建構篩選條件表達式的 DynamoDB 資料表 AWS SDK for Python (Boto3)。

import boto3 from boto3.dynamodb.conditions import Attr, Key def query_with_dynamic_filter( table_name, partition_key_name, partition_key_value, filter_conditions=None ): """ Query a DynamoDB table with a dynamically constructed filter expression. Args: table_name (str): The name of the DynamoDB table. partition_key_name (str): The name of the partition key attribute. partition_key_value (str): The value of the partition key to query. filter_conditions (dict, optional): A dictionary of filter conditions where keys are attribute names and values are dictionaries with 'operator' and 'value'. Example: {'rating': {'operator': '>=', 'value': 4}, 'status': {'operator': '=', 'value': 'active'}} Returns: dict: The response from DynamoDB containing the query results. """ # Initialize the DynamoDB resource dynamodb = boto3.resource("dynamodb") table = dynamodb.Table(table_name) # Start with the key condition expression key_condition = Key(partition_key_name).eq(partition_key_value) # Initialize variables for the filter expression and attribute values filter_expression = None expression_attribute_values = {":pk_val": partition_key_value} # Dynamically build the filter expression if filter conditions are provided if filter_conditions: for attr_name, condition in filter_conditions.items(): operator = condition.get("operator") value = condition.get("value") attr_value_name = f":{attr_name}" expression_attribute_values[attr_value_name] = value # Create the appropriate filter expression based on the operator current_condition = None if operator == "=": current_condition = Attr(attr_name).eq(value) elif operator == "!=": current_condition = Attr(attr_name).ne(value) elif operator == ">": current_condition = Attr(attr_name).gt(value) elif operator == ">=": current_condition = Attr(attr_name).gte(value) elif operator == "<": current_condition = Attr(attr_name).lt(value) elif operator == "<=": current_condition = Attr(attr_name).lte(value) elif operator == "contains": current_condition = Attr(attr_name).contains(value) elif operator == "begins_with": current_condition = Attr(attr_name).begins_with(value) # Combine with existing filter expression using AND if current_condition: if filter_expression is None: filter_expression = current_condition else: filter_expression = filter_expression & current_condition # Perform the query with the dynamically built filter expression query_params = {"KeyConditionExpression": key_condition} if filter_expression: query_params["FilterExpression"] = filter_expression response = table.query(**query_params) return response

示範如何使用動態篩選條件表達式 AWS SDK for Python (Boto3)。

def example_usage(): """Example of how to use the query_with_dynamic_filter function.""" # Example parameters table_name = "Products" partition_key_name = "Category" partition_key_value = "Electronics" # Define dynamic filter conditions based on user input or runtime conditions user_min_rating = 4 # This could come from user input user_status_filter = "active" # This could come from user input filter_conditions = {} # Only add conditions that are actually specified if user_min_rating is not None: filter_conditions["rating"] = {"operator": ">=", "value": user_min_rating} if user_status_filter: filter_conditions["status"] = {"operator": "=", "value": user_status_filter} print( f"Querying products in category '{partition_key_value}' with filter conditions: {filter_conditions}" ) # Execute the query with dynamic filter response = query_with_dynamic_filter( table_name, partition_key_name, partition_key_value, filter_conditions ) # Process the results items = response.get("Items", []) print(f"Found {len(items)} items") for item in items: print(f"Product: {item}")
  • 如需 API 的詳細資訊,請參閱《適用於 Python (Boto3) 的AWS SDK API 參考》中的 Query