查找未设置 DynamoDB 属性*或*大于 x 的项目

Find items where DynamoDB attribute is not set *or* greater than x

我正在尝试从 Lambda (Node.js) 扫描 DynamoDB table 以检查令牌是否已过期。我想过滤数据以排除设置了 expiration_time 且小于当前时间的项目。对于未设置 expiration_time 的单位,我目前得到误报。

如何检查过期时间戳 根本没有 expiration_time 属性集?

dynamodb.scan({
    "TableName": "fm_tokens",
    "AttributesToGet": ["user_id"],
    "ScanFilter": {
        "token": {
            "AttributeValueList": [{"S": tkn.toString()}],
            "ComparisonOperator": "EQ"
        },
        "token_time": {
            "AttributeValueList": [{"N": expiration.toString()}],
            "ComparisonOperator": "GE"
        },
        "expiration_time": {
            "AttributeValueList": [{"N": unix_timestamp.toString()}],
            "ComparisonOperator": "GE",
        }
    }
}

事实证明,执行 "OR" 操作的最佳方法是使用新的 string-based 过滤命令。 AttributesToGet 替换为 ProjectionExpressionScanFilter 替换为 FilterExpression

请注意,对于新命令,您将无法使用 reserved words,并且必须通过使用 ExpressionAttributeNames 定义这些键和使用 ExpressionAttributeValues 定义任何值来解决任何保留字。

dynamodb.scan({
  // Define table to scan
    "TableName": "fm_tokens",
  // Only return selected values (optional)
    "ProjectionExpression": "user_id",
  // Write your expression, similar to SQL syntax
    "FilterExpression": 
        "#token = :tkn AND "+
        "token_time >= :expiration AND "+
        "(attribute_not_exists(expiration_time) OR expiration_time >= :timestamp)",
  // Use this to avoid reserved words by defining variables with the name instead
    "ExpressionAttributeNames": {
        "#token": "token"
    },
  // Same as with names, but for values - must include value type (S, N, etc.)
    "ExpressionAttributeValues": {
        ":tkn": {"S": tkn},
        ":expiration": {"N": expiration.toString()},
        ":timestamp": {"N": unix_timestamp.toString()}
    }
}