我正在尝试查询DynamoDB表,并检查表索引的分区键中是否包含我传递的查询。
例如,我有一个DynamoDB表,下面是示例数据。
+-----+----------------+---------------------------------------------+
| id | title | description |
+-----+----------------+---------------------------------------------+
| id1 | My Title One | This is an awesome item in my database |
| id2 | My Title Two | This is also an awesome item in my database |
| id3 | The Item Three | Hello World |
+-----+----------------+---------------------------------------------+
我在属性title
上有一个全局索引。主分区键是id
。
我要做的是从用户那里进行搜索查询,并匹配标题的所有项目。
我有以下代码将用户术语与标题完全匹配。
const params = {
ExpressionAttributeValues: {
":q": {
S: req.query.q
}
},
KeyConditionExpression: "title = :q",
TableName: "MyTable",
IndexName: 'title-index'
};
dynamodb.query(params, (err, titles) => {
if (err) {
return res.status(500).send({"Error": "Error"});
}
titles = titles.Items
.map(item => AWS.DynamoDB.Converter.unmarshall(item));
return res.send(titles);
});
因此,如果用户搜索My Title One
,它将返回ID为id1
的结果。现在,我想增加对用户输入My Title
的支持,我希望它返回ID的id1
和id2
。当前,它什么也不返回,因为没有完全匹配。
我知道使用DynamoDB扫描而不是查询是可行的,但是由于我的表有很多项目,因此在这种情况下进行扫描似乎在性能和成本上都效率很低。 / p>
最简单的方法是什么?
答案 0 :(得分:1)
您将无法通过DynamoDB查询执行此操作。 DynamoDB查询需要与主键进行完全相等的比较。正如您指出的那样,您将不得不使用扫描,扫描效率可能非常低且昂贵,具体取决于表的大小。
即使高效且廉价,扫描仍然不是实现搜索功能的理想选择。如果您的用户搜索“我的标题”怎么办? Dynamo没有执行不区分大小写的字符串比较的功能。您将不得不在表中存储另一个属性,其中包含要扫描和过滤的字段的可搜索性更高的版本。
如果您需要真正的搜索功能,则需要使用其他功能。连接Dynamo和ElasticSearch(如果您知道ElasticSearch)“相对”容易。您可以在表更改时使用带有Lambda触发器的DynamoDB流来插入/更新/删除ElasticSearch索引。然后,您将对ElasticSearch执行标题搜索。如果您以前使用过ElasticSearch,那还不错。如果不是这样,则存在一些学习曲线。
您可能不想听的另一种选择是放弃Dynamo并使用关系数据库,并使用带有一些通配符的LIKE查询。
不幸的是,没有一种很好的方法可以仅在Dynamo之上实现体面的搜索。