我通过dynamoose使用dynamoDb,并尝试使用过滤和排序。
我有二级索引作为分区键(组织id)和排序键(名字)。
我想用同一列排序,也想用同一列过滤,我使用下面的查询:
users.query("organization_id").eq(user_organization_id).filter('first_name').conatins(first_name).sort('ascending').using('organization_id_first_name_index').exec();
显示错误
Filter Expression can only contain non-primary key attributes: Primary key attribute: first_name
预期结果是筛选和排序将顺利运行
DynamoDB的Query操作有两个不同的参数——KeyConditionExpression
和FilterExpression
。前者是一个高效的机制,可以直接跳转到所需的键,后者是一个过滤器,它会检查KeyConditionExpression
返回的所有结果(你要为阅读所有结果付费!),并决定每个结果是否通过过滤器。
正如DynamoDB告诉你的,FilterExpression
不想在排序键上工作,因为在KeyConditionExpression
中选择排序键会更有效。
你可以争辩说你不能使用"contains()"使用KeyConditionExpression
,但这表明您的数据模型不是最优的-没有办法实现您的contains()请求而不读取整个分区。你确定你真的想检查contains()而不是eq()吗?
DynamoDB按排序键的升序排序,因此不需要解决排序方面的问题。
对于FilterExpression,对于键属性使用KeyConditionExpression,因为它的目的是针对表或索引键,并且比FilterExpression更有效。
contains
不是你可以在排序键上执行的东西,它必须是equal, begins_with, greater_than, less_than,也许还有更多,但主要的一点是它们都知道排序键的开始。注意,不能执行ends_with。如果你读过b树是如何工作的,你就会理解其中的逻辑。
users.query("organization_id").eq(user_organization_id).filter('first_name').eq(first_name).sort('ascending').using('organization_id_first_name_index').exec();