我有一个包含数千条数据的DynamoDb表。我使用Scan函数扫描该表,并应用了“Between”FilterExpression。然而,查询响应仅返回3条记录,而应该返回约100条记录。
我使用Node js创建了Lambda函数。
我有一个包含数千条数据的DynamoDb表。我使用Scan函数扫描该表,并应用了“Between”FilterExpression。然而,查询响应仅返回3条记录,而应该返回约100条记录。
我使用Node js创建了Lambda函数。
另一个常见问题可能是扫描是否执行到LastEvaluatedKey为空。
如果您已经这样做了,但仍然没有获取到所有的项,请展示您的代码以便详细查看。
如果扫描的总项数超过1 MB的最大数据集大小限制,则扫描将停止并将结果作为LastEvaluatedKey值返回给用户,以便在随后的操作中继续扫描。结果还包括超过限制数量的项目数。扫描可能导致没有满足筛选条件的表数据。
如果LastEvaluatedKey为空,则表示已处理完结果的“最后一页”,没有更多数据可供检索。
如果LastEvaluatedKey不为空,这并不一定意味着结果集中还有更多数据。唯一确定已经到达结果集末尾的方法是LastEvaluatedKey为空时。
这是一个获取所有结果的示例代码:
Map<String, AttributeValue> lastKeyEvaluated = null;
do {
ScanRequest sr = new ScanRequest()
.withTableName("tableName")
.withProjectionExpression("id")
.withExclusiveStartKey(lastKeyEvaluated);
ScanResult result = client.scan(sr);
for (Map<String, AttributeValue> item : result.getItems()) {
System.out.println(item.get("id").getS());
}
lastKeyEvaluated = result.getLastEvaluatedKey();
} while (lastKeyEvaluated != null);
result.getLastEvaluatedKey()
返回一个空的、而不是 null 的 map。因此,我只需要将 while
条件更改为检查 != null && !empty
即可。 - dewald使用 Node.js,我正在使用查询从数据库检索项目。一个单独的查询操作最多可以检索 1 MB 的数据。这就是为什么我创建了一个递归函数来从数据库检索并连接数据,直到我们从响应中接收到 LastEvaluatedKey
为止。
当我们收到值为 null
的 LastEvaluatedKey
时,表示没有更多数据了。
我的函数使用索引从数据库中获取数据。使用查询功能将比扫描更快、更有效。
实际上,getItemByGSI
函数具有许多用于查询过滤和自定义的参数,这可能会很有用。当然,您可以删除对用例不必要的参数。
因此,getAllItemsByGSI
函数可用于检索 DynamoDB 中的所有数据,而 getItemByGSI
可用于使用单个查询。
'use strict';
const omitBy = require('lodash/omitBy');
const isNil = require('lodash/isNil');
const AWS = require('aws-sdk');
const call = (action, params) => {
return new Promise((resolve, reject) => {
try {
const dynamoDb = new AWS.DynamoDB.DocumentClient();
resolve(dynamoDb[action](params).promise());
} catch (error) {
reject(error);
}
});
};
const getItemByGSI = ({
TableName,
IndexName,
attribute,
value,
sortKey,
sortValue,
filter,
filterValue,
operator,
filter1,
filterValue1,
LastEvaluatedKey,
ScanIndexForward,
Limit,
}) => {
return new Promise(async (resolve, reject) => {
try {
const params = {
TableName,
IndexName,
KeyConditionExpression: '#attrKey = :attrValue',
ExpressionAttributeValues: { ':attrValue': value },
ExpressionAttributeNames: { '#attrKey': attribute },
ExclusiveStartKey: LastEvaluatedKey,
Limit,
FilterExpression: null,
};
sortKey && sortValue
? (params.KeyConditionExpression +=
' and #sortKey = :sortValue' &&
(params.ExpressionAttributeNames['#sortKey'] = sortKey) &&
(params.ExpressionAttributeValues[':sortKey'] = sortValue))
: '';
filter && filterValue
? (params.FilterExpression = `#${filter} = :${filter}`) &&
(params.ExpressionAttributeNames[`#${filter}`] = filter) &&
(params.ExpressionAttributeValues[`:${filter}`] = filterValue)
: '';
filter && filterValue && operator && filter1 && filterValue1
? (params.FilterExpression += ` ${operator} #${filter1} = :${filter1}`) &&
(params.ExpressionAttributeNames[`#${filter1}`] = filter1) &&
(params.ExpressionAttributeValues[`:${filter1}`] = filterValue1)
: '';
params = omitBy(params, isNil);
if (ScanIndexForward === false)
params.ScanIndexForward = ScanIndexForward;
const result = await call('query', params);
resolve(result);
} catch (error) {
reject(error);
}
});
};
const getAllItemsByGSI = (data) => {
return new Promise(async (resolve, reject) => {
try {
const finalData = [];
const gettingData = await getItemByGSI(data);
finalData = finalData.concat(gettingData.Items);
if (gettingData.LastEvaluatedKey) {
const final2 = await getAllItemsByGSI({
...data,
LastEvaluatedKey: gettingData.LastEvaluatedKey,
});
finalData = finalData.concat(final2);
}
resolve(finalData);
} catch (err) {
reject(err);
}
});
};
module.exports = {
getItemByGSI,
getAllItemsByGSI,
};
Node.js
从AWS Dynamodb
获取/扫描所有项,您可以参考以下链接:https://dev59.com/CVcP5IYBdhLWcg3wTYYn - Yuci