[英]Scan Function in DynamoDB with reserved keyword as FilterExpression NodeJS
[英]AWS DynamoDB Scan and FilterExpression using array of hash values
我很难找到一个有用的示例,用于在 DynamoDB 表上使用 FilterExpression 进行扫描。 我在浏览器中使用 javascript SDK。
我想扫描我的表并只返回那些在传递给 Scan 的数组中具有 HASH 字段“UID”值的记录
假设我有一组唯一 ID,它们是我的表的哈希字段,我想从我的 DynamoDB 表中查询这些记录。
像下面这样
var idsToSearch=['123','456','789'] //array of the HASH values I would like to retrieve
var tableToSearch = new AWS.DynamoDB();
var scanParams = {
"TableName":"myAwsTable",
"AttributesToGet":['ID','COMMENTS','DATE'],
"FilterExpression":"'ID' in "+idsToSearch+""
}
tableToSearch.scan(scanParams), function(err,data){
if (err) console.log(err, err.stack); //error handler
else console.log(data); //success response
})
您应该使用IN
运算符。 对属性名称和属性值使用占位符也更容易。 但是,我建议不要在这种情况下使用Scan
。 听起来您已经拥有要查找的哈希键属性值,因此使用BatchGetItem
会更有意义。
无论如何,以下是您在 Java 中的处理方式:
ScanSpec scanSpec = new ScanSpec()
.withFilterExpression("#idname in (:val1, :val2, :val3)")
.withNameMap(ImmutableMap.of("#idname", "ID"))
.withValueMap(ImmutableMap.of(":val1", "123", ":val2", "456", ":val23", "789"));
ItemCollection<ScanOutcome> = table.scan(scanSpec);
我想使用 Javascript SDK 会是这样的:
var scanParams = {
"TableName":"myAwsTable",
"AttributesToGet": ['ID','COMMENTS','DATE'],
"FilterExpression": '#idname in (:val1, :val2, :val3)',
"ExpressionAttributeNames": {
'#idname': 'ID'
},
"ExpressionAttributeValues": {
':val1': '123',
':val2': '456',
':val3': '789'
}
}
我遇到了这个问题并通过使用contains参数解决了这个问题
// Object stored in the DB looks like this:
// [
// 'name' => 'myName',
// 'age' => '24',
// 'gender' => 'Male',
// 'visited' => [
// 'countries': ['Canada', 'USA', 'Japan', 'Australia'],
// 'last_trip': '2015/12/13',
// 'reviews_written': 20
// ]
//
// ];
$countries = ['Canada', 'USA', 'Japan', 'Australia'];
$paramToMatch = '24';
$client->query([
'TableName' => 'MyDyanmoDB',
'KeyConditions' => [
'age' => [
'AttributeValueList' => [
$marshaler->marshalValue($paramToMatch)
],
'ComparisonOperator' => 'EQ'
]
],
'ExpressionAttributeNames' => [
'#visited' => 'visited',
'#countries' => 'countries'
],
'ExpressionAttributeValues' => [
':countries' => $marshaler->marshalValue($countries)
],
'FilterExpression' => 'contains(:countries, #visited.#countries)',
]);
下面是我如何使用“扫描”来获取具有特定 ID(“ContentID”)的项目,如下例所示:
var params = {
TableName: environment.ddbContentTableName,
ProjectionExpression: "Title, ContentId, Link",
FilterExpression: "ContentId in (:contentId1, :contentId2, :contentId3, :contentId4)",
ExpressionAttributeValues: {":contentId1":102,":contentId2":104,":contentId3":103,":contentId4":101}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.scan(params, onQuery);
然后我可以根据已知值以编程方式构建 FilterExpression 和 ExpressionAttributeValues,例如
// Create the FilterExpression and ExpressionAttributeValues
var filterExpression = "ContentId in (";
var expressionAttributeValues = {};
for (var i = 0; i < currentFavorites.length; i++) {
var contentIdName = ":contentId"+(i+1);
if (i==0) {
filterExpression = filterExpression + contentIdName;
} else {
filterExpression = filterExpression + ", " + contentIdName;
}
expressionAttributeValues[contentIdName] = currentFavorites[i];
}
filterExpression = filterExpression + ")";
var params = {
TableName: environment.ddbContentTableName,
ProjectionExpression: "Title, ContentId, Link",
FilterExpression: filterExpression,
ExpressionAttributeValues: expressionAttributeValues
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.scan(params, onQuery);
我也在寻找一种动态解决方案,而不是手动将每个参数名称放入条件表达式中。 下面是一个解决方案:
List<String> valList= new ArrayList<String>(); // Populate the Values in a List
StringJoiner valMap = new StringJoiner(","); // This will be the dynamic Value Map
int i=1;
table = dynamoDB.getTable(myTable);
StringBuilder filterExpression = new StringBuilder();
Map<String, Object> eav = new HashMap<String, Object>();
if(!valList.isEmpty())
{
for(String attrVal: valList)
{
eav.put(":val"+i, attrVal);
valMap.add(":val"+i);
i++;
}
filterExpression.append("attrColName in ("+valMap.toString()+")"); //here attrColName is the DB attribute
}
ItemCollection<ScanOutcome> items;
items = table.scan(
filterExpression.toString(), //FilterExpression
null, //ProjectionExpression - choose all columns
null, //ExpressionAttributeNames - not used in this example
eav);//ExpressionAttributeValues
var params = {
TableName: "tableOne",
ProjectionExpression: "Title, ContentId, Link",
FilterExpression: "ContentId in (:contentIds)",
ExpressionAttributeValues: {":contentIds":[11,22,33,44,55]}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.scan(params);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.