Amazon dynamodb 使用“查询DynamoDB项目”;包括「;
假设我有一个DynamoDB表,比如Amazon dynamodb 使用“查询DynamoDB项目”;包括「;,amazon-dynamodb,Amazon Dynamodb,假设我有一个DynamoDB表,比如 TableName: 'Items' Key: {Hash: 'Id'} 每个项目都有一个名称,属于一个客户,所以我也有一个索引 {Hash: CustomerId, Range:Name} 假设我有以下数据: Id CustomerId Name 1 18 Milk 2 42 Orange juice 3 42 Apple juice 4 42
TableName: 'Items'
Key: {Hash: 'Id'}
每个项目都有一个名称,属于一个客户,所以我也有一个索引
{Hash: CustomerId, Range:Name}
假设我有以下数据:
Id CustomerId Name
1 18 Milk
2 42 Orange juice
3 42 Apple juice
4 42 Coffee
5 54 Tomato juice
现在,我想查询特定客户的所有项目,并过滤部分名称的结果(本质上是一个搜索操作)。例如,给我所有属于客户42且名称中包含“果汁”的项目(橙汁和苹果汁是预期结果)
如果我查询CustomerId='42'并包含(Name,'juice')
我将得到一个错误,说明KeyConditionExpression
不支持contains
。我可以理解这个限制,因为包含意味着必须扫描所有项目(在给定的散列键内),但是,您可以使用CustomerId='42'
查询所有项目,这也是该散列中的完全扫描,所以我不确定是否理解这个限制。像以
开头这样的事情也像预期的那样得到支持(这很有意义,因为很容易从排序集快速返回子集)
不管怎么说,我诅咒了一点,说我将只使用FilterExpression来代替,并使用浪费的RCU:s,从而产生一个带有
KeyConditionExpression: CustomerId = '42'
FilterExpression: contains(Name, 'juice')
但是现在我得到一个错误,说我不允许在我的FilterExpression中包含主键属性(“改用KeyConditionExpression!”)
这让我有些进退两难。我无法在我的KeyCondition
中使用contains
进行筛选,也无法在我的FilterExpression中使用Name
进行筛选。为了实现我的用例,我是否必须创建一个单独的索引,或者有其他的方法来解决这个问题吗? < P>对于这样的东西,你应该考虑组合键和GSI重载的概念,并重新设计你的表来适应你的访问模式。< /P>
依照
使用复合属性。尝试将多个属性组合到
如果符合您的访问模式,则形成唯一密钥。例如
考虑使用Cuffer-ID+CudiTiD+国家代码的订单表
分区键和订单日期作为排序键
因此,您可以做一些事情,例如将表设计为包含customerid\35name
索引,DynamoDB仅允许在关键字条件下使用begin\u,因此不支持contains,但对于您的情况,可以按分层顺序排列rangeKey,如:
客户ID名称
18牛奶
42.橙汁
42.苹果汁
42咖啡
54番茄汁
因此,查询的结构可以如下所示
KeyConditionExpression:CustomerId='42',名称以'juice'开头
对于DynamoDB,我认为最好的解决方案是将数据存储在您稍后打算读取的形状中
如果您发现自己需要复杂的读取查询,那么您可能会陷入期望DynamoDB像RDBMS一样工作的陷阱,而事实并非如此。在写操作中转换和塑造数据,使读操作保持简单。此查询的行为类似于关系数据库中的查询
database.scan()
.filterExpression('begins_with(#name ,:name) or begins_with(#someno,:name)')
.expressionAttributeNames({ "#name": "name","#someno":"someno"})
.expressionAttributeValues({ ":name" : data})
.exec().promise();
只需复制属性并在其上应用过滤器即可谢谢,但不确定这有何帮助。使用contains的唯一方法似乎是在filter表达式中,filter表达式只能对非键进行操作。如果我将customerId和name组合成一个字符串并将其用作散列键,则无法查询属于特定客户的所有项目,并且仍然无法使用contains。我误解了吗?多么令人沮丧,多么有趣!创建一个全新的索引将非常昂贵。您最好复制Name属性(一个名为NameKey,另一个名为Name)。然后,您可以在非键名称字段上使用FilterExpression,就像第二次尝试时一样。还是垃圾,但是便宜点。谢谢斯图。我确实想到了,但感觉。。像你说的垃圾。不过,这可能是最好的妥协。如果能得到aws的官方回复,那就太酷了,我可能也会把帖子复制到aws论坛上。你是如何最终解决这个问题的,因为我现在面临着同样的问题已经有一段时间了,但如果我的记忆正确的话,我最终做了客户端过滤,因为我每个客户的数据集都相当小。谢谢,这是一个有趣的方法。如果您需要查询的基本上是类别之类的东西,那么这可能会起作用。然而,在我的特定用例中,数据更加复杂,例如查找具有部分URI:s的项等,因此不可能按层次重新排列它。不确定您是否阅读了问题。我知道查询是如何工作的,谢谢,但是我在DynamoDB中遇到了一个限制,因为KeyConditionExpression不支持contains。我不知道你的回答是怎么说的对不起伙计我的错