我正在尝试使用 IN 过滤器查询 DynamoDB 表。当我将单个值传递给 IN 时,我的查询有效,但是当我传递多个值时,我没有得到匹配项。
这是 params 对象的初始设置。
var params = {
TableName: "Interactions",
IndexName: "environment-time-index",
KeyConditionExpression: "#environment = :environment and #time between :start and :end",
FilterExpression: "#product = :product",
ExpressionAttributeNames: {
"#product": "product",
"#environment": "environment",
"#time": "time"
},
ExpressionAttributeValues: {
":product": product,
":environment": environment,
":start": start,
":end": end
}
};
Run Code Online (Sandbox Code Playgroud)
接下来,如果用户提供了一个确定的查询参数,我会像这样修改 params 对象。这是我使用 IN 运算符的地方。
if (req.query.firm) {
var firms = req.query.firm;
console.log('debug', firms);
params.FilterExpression += " AND #firmCode IN (:firms)";
params.ExpressionAttributeNames["#firmCode"] = "firmCode";
params.ExpressionAttributeValues[":firms"] = firms;
}
Run Code Online (Sandbox Code Playgroud)
最后,我像这样运行查询。
docClient.query(params, function(err, data) {
if (err) {
log.error(`Unable to scan. Error: ${JSON.stringify(err, null, 2)}`);
res.status(500).json({ error: "Oh, snap!" });
} else {
data.Parameters = params.ExpressionAttributeValues;
log.info(`Scan succeeded. Received ${data.Count} items.`)
res.send(data);
}
});
Run Code Online (Sandbox Code Playgroud)
当公司参数包含单个值时,我会返回结果。
Level="INFO", Date="2016-09-19 14:26:03,373", Message="batchinsight received GET for /api/history/interactions2", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
debug TW7ZN
Level="INFO", Date="2016-09-19 14:26:03,623", Message="Scan succeeded. Received 19 items.", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
Run Code Online (Sandbox Code Playgroud)
但是当它包含多个值时,我没有得到任何结果。
Level="INFO", Date="2016-09-19 14:35:16,896", Message="batchinsight received GET for /api/history/interactions2", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
debug TW7ZN,TEXK4
Level="INFO", Date="2016-09-19 14:35:16,991", Message="Scan succeeded. Received 0 items.", Product="Exhaust", Service="batchinsight", AppDomain="Exhaust_batchinsight"
Run Code Online (Sandbox Code Playgroud)
DynamoDB 文档建议 IN 运算符可以接受逗号分隔的值列表,但我无法让它工作。请帮忙! http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html#ConditionExpressionReference
很容易假设 IN 运算符接受一个字符串列表,但请记住,这是 DynamoDB,因此它需要一个变量列表。IE(:string1, :string2)
我在这里写了一个要点,下面是该要点的简化版本。
const listToObjectMappings = (list) => {
let x = {}
list.map(item => x[':' + item] = item)
return x
}
let statuses = ['available', 'in-transit', 'delivered']
let mappings = listToObjectMappings(statuses)
let joined = Object.keys(mappings).join();
query = {
FilterExpression: '#stat IN (' + joined + ')',
ExpressionAttributeNames: {
'#stat' : 'status'
},
ExpressionAttributeValues: mappings
}
Run Code Online (Sandbox Code Playgroud)
编辑:要点实际上更安全。此版本不适用于包含重复值的列表。但如果每个项目都是独一无二的,那就没问题了。
实际上,您指的是ConditionExpression参考文档,它与FilterExpression不同。
条件表达式表示您在表中读取(请不要将此与查询/扫描混淆)和写入项目时要实施的限制。
您实际上正在查询该表。FilterExpression用于查询和扫描数据。
IN :检查两个集合内的匹配元素。AttributeValueList 可以包含一个或多个 String、Number 或 Binary (非集合类型)类型的 AttributeValue 元素。这些属性将与项目的现有集合类型属性进行比较。如果输入集的任何元素出现在 item 属性中,则表达式的计算结果为 true。
请注意,IN 用于检查 SET 数据类型中是否存在单个值。
您可以参考这里的类似帖子,其中 OR 条件用于比较 SET 数据类型中的多个值。
同样,如果公司代码是 STRING 或 SET 数据类型,则应使用OR 条件。
| 归档时间: |
|
| 查看次数: |
6801 次 |
| 最近记录: |