Javascript DynamoDB索引查询包括

Javascript DynamoDB索引查询包括,javascript,amazon-web-services,amazon-dynamodb,dynamodb-queries,Javascript,Amazon Web Services,Amazon Dynamodb,Dynamodb Queries,我试图查询DynamoDB表,并检查传入的查询是否包含在表索引的分区键中 例如,我有一个DynamoDB表,下面是示例数据 +-----+----------------+---------------------------------------------+ | id | title | description | +-----+----------------+----------------------

我试图查询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                                 |
+-----+----------------+---------------------------------------------+
我在属性
标题
上有一个全局索引。主分区键是
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);
});
我有下面的代码将用户术语与标题完全匹配

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扫描而不是查询可以做到这一点,但由于我的表有这么多项,在这种情况下进行扫描在性能和成本方面似乎效率很低


实现这一点最简单的方法是什么?

使用DynamoDB查询无法做到这一点。DynamoDB查询需要与主键进行精确的equals比较。您必须使用扫描,正如您所指出的,根据您的表的大小,扫描可能非常低效且昂贵

即使扫描既高效又便宜,但它仍然不是实现搜索功能的最佳选择。如果您的用户搜索“我的标题”,该怎么办?Dynamo没有用于进行不区分大小写的字符串比较的函数。您必须在表中存储另一个属性,其中包含要扫描和筛选的字段的更可搜索版本

如果您需要真正的搜索功能,那么您将需要使用其他功能。连接Dynamo和ElasticSearch“相对”容易(如果您知道ElasticSearch)。可以使用带有Lambda触发器的DynamoDB流在表更改时插入/更新/删除ElasticSearch索引。然后,您将针对ElasticSearch执行标题搜索。如果您以前使用过ElasticSearch,那就没那么糟糕了。如果不是,则有一点学习曲线

另一种可能您不想听的选择是抛弃Dynamo,使用关系数据库,使用带有通配符的LIKE查询

不幸的是,除了Dynamo之外,没有一个好的方法来实现一个像样的搜索