问题描述
我开始在这里学习 Dynamodb,目前正在尝试在我的表上进行搜索,其中 PK 是分区键,SK 是范围键。 PK 包含电子邮件地址,而 SK 包含诸如 AB_STATE
、BC_STATE
、MY_STATE
之类的值。因此,我想在值以 MY_
开头的 SK 中进行搜索,但我不完全确定如何使用 .get()
函数进行搜索。
这是我的查询 Seller.get({ "PK": "imin@cats.com","SK" : "MY" })
,它显然不是我想要的。
我知道我也许可以使用像下面这样的过滤器,但我在很多地方读到不推荐使用过滤器 (?)
var filter = new dynamoose.Condition().where("PK").eq(email).filter("SK").beginsWith("MY_");
var premiseProfile = await Seller.query(filter).exec()
以下是我的卖家表的架构
const schema = new dynamoose.Schema({
PK: {
type: String,hashKey: true,},SK: {
type: String,rangeKey: true,"firstName": String,"lastName": String,"gender": {
"type": Number,"default": 0
},{
"saveUnkNown": true,"timestamps": true
});
解决方法
执行 Model.get
调用时,您必须传入整个密钥。您不能传入以 开头的键。这是因为 Model.get
将只返回 1 个项目,并且查询表明您可以在那里有多个项目。
由于您没有发布架构,因此很难准确回答您的问题。但在这种情况下执行 query
看起来还不错,因为您是在查询数据而不是过滤数据。
基于评论的更多信息。
我意识到 condition.filter
documentation 并没有真正涵盖这一点。基本上取决于您的架构,它将确定最佳索引,并以它知道的最佳方式对其进行优化。
例如,如果您有以下代码:
const dynamoose = require("dynamoose");
(async () => {
dynamoose.model.defaults.set({
"create": false,"waitForActive": false
});
const schema = new dynamoose.Schema({
"PK": {
"type": String,"hashKey": true
},"SK": {
"type": String,"rangeKey": true
}
});
const Model = dynamoose.model("User",schema);
dynamoose.logger.providers.add(console);
const filter = new dynamoose.Condition().where("PK").eq("test@test.com").filter("SK").beginsWith("MY_");
const premiseProfile = await Model.query(filter).exec()
})();
它将产生以下输出:
aws:dynamodb:query:request - {
"ExpressionAttributeNames": {
"#qha": "PK","#qra": "SK"
},"ExpressionAttributeValues": {
":qhv": {
"S": "test@test.com"
},":qrv": {
"S": "MY_"
}
},"TableName": "User","KeyConditionExpression": "#qha = :qhv AND begins_with (#qra,:qrv)"
}
如您所见,它使用的是 KeyConditionExpression
而不是 FilterExpression
。
所以你没有过滤。如果对您更有意义,您可以使用 condition.where
或 condition.attribute
。
需要注意的是,在某些情况下它会使用 FilterExpression
。但它会首先查看您的架构并尝试查看它是否可以使用 KeyConditionExpression
,如果可以,它将使用它,否则它将使用 FilterExpression
。