如何使用 Dynamoose 正确查询索引
How do I query an index properly with Dynamoose
我正在使用 Dynamoose 来简化我在 node.js 应用程序中与 DynamoDB 的交互。我正在尝试使用 Dynamoose 的 Model.query 函数编写查询,该函数将使用索引搜索 table,但 Dynamoose 似乎不包括处理查询所需的所有信息,我是不确定我做错了什么。
架构如下所示:
const UserSchema = new dynamoose.Schema({
"user_id": {
"hashKey": true,
"type": String
},
"email": {
"type": String,
"index": {
"global": true,
"name": "email-index"
}
},
"first_name": {
"type": String,
"index": {
"global": true,
"name": "first_name-index"
}
},
"last_name": {
"type": String,
"index": {
"global": true,
"name": "last_name-index"
}
}
)
module.exports = dynamoose.model(config.usersTable, UserSchema)
我希望能够通过电子邮件地址搜索用户,因此我正在编写如下所示的查询:
Users.query("email").contains(query.email)
.using("email-index")
.all()
.exec()
.then( results => {
res.status(200).json(results)
}).catch( err => {
res.status(500).send("Error searching for users: " + err)
})
我为电子邮件字段定义了一个全局二级索引:
当我尝试执行此查询时,出现以下错误:
Error searching for users: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.
使用 Dynamoose 调试输出,我可以看到查询最终看起来像这样:
aws:dynamodb:query:request - {
"FilterExpression": "contains (#a0, :v0)",
"ExpressionAttributeNames": {
"#a0": "email"
},
"ExpressionAttributeValues": {
":v0": {
"S": "mel"
}
},
"TableName": "user_qa",
"IndexName": "email-index"
}
我注意到发送到 DynamoDB 的实际查询不包含 KeyConditions 或 KeyConditionExpression,如错误消息所示。我做错了什么阻止正确编写此查询,以便它针对我为此添加的全局二级索引执行查询 table?
我对 Dynamoose 不太熟悉,但下面的代码将使用 node.JS 和 DynamoDB 对记录进行更新。请参阅下面的关键参数;根据您收到的错误消息,您似乎错过了这个。
据我所知,您必须为 UPDATE 请求指定密钥。您可以查看 AWS DynamoDB 文档来确认。
var params = {
TableName: table,
Key: {
"id": customerID,
},
UpdateExpression: "set customer_name= :s, customer_address= :p, customer_phone= :u, end_date = :u",
ExpressionAttributeValues: {
":s": customer_name,
":p": customer_address,
":u": customer_phone
},
ReturnValues: "UPDATED_NEW"
};
await docClient.update(params).promise();
事实证明,像 .contains(text)
这样的调用被用作 过滤器 ,而不是查询参数。 DynamoDB 在不查看每条记录的情况下无法确定索引中的文本是否包含我正在搜索的文本,这是扫描,而不是查询。因此,在这种情况下尝试使用 .contains(text)
没有任何意义,即使可以像我构建的那样在链中调用它。为了完成这项工作,我最终需要做的是将我的调用转换为使用 .contains(text)
过滤器的 table 扫描:
Users.scan({ email: { contains: query.email }}).all().exec().then( ... )
我正在使用 Dynamoose 来简化我在 node.js 应用程序中与 DynamoDB 的交互。我正在尝试使用 Dynamoose 的 Model.query 函数编写查询,该函数将使用索引搜索 table,但 Dynamoose 似乎不包括处理查询所需的所有信息,我是不确定我做错了什么。
架构如下所示:
const UserSchema = new dynamoose.Schema({
"user_id": {
"hashKey": true,
"type": String
},
"email": {
"type": String,
"index": {
"global": true,
"name": "email-index"
}
},
"first_name": {
"type": String,
"index": {
"global": true,
"name": "first_name-index"
}
},
"last_name": {
"type": String,
"index": {
"global": true,
"name": "last_name-index"
}
}
)
module.exports = dynamoose.model(config.usersTable, UserSchema)
我希望能够通过电子邮件地址搜索用户,因此我正在编写如下所示的查询:
Users.query("email").contains(query.email)
.using("email-index")
.all()
.exec()
.then( results => {
res.status(200).json(results)
}).catch( err => {
res.status(500).send("Error searching for users: " + err)
})
我为电子邮件字段定义了一个全局二级索引:
当我尝试执行此查询时,出现以下错误:
Error searching for users: ValidationException: Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.
使用 Dynamoose 调试输出,我可以看到查询最终看起来像这样:
aws:dynamodb:query:request - {
"FilterExpression": "contains (#a0, :v0)",
"ExpressionAttributeNames": {
"#a0": "email"
},
"ExpressionAttributeValues": {
":v0": {
"S": "mel"
}
},
"TableName": "user_qa",
"IndexName": "email-index"
}
我注意到发送到 DynamoDB 的实际查询不包含 KeyConditions 或 KeyConditionExpression,如错误消息所示。我做错了什么阻止正确编写此查询,以便它针对我为此添加的全局二级索引执行查询 table?
我对 Dynamoose 不太熟悉,但下面的代码将使用 node.JS 和 DynamoDB 对记录进行更新。请参阅下面的关键参数;根据您收到的错误消息,您似乎错过了这个。
据我所知,您必须为 UPDATE 请求指定密钥。您可以查看 AWS DynamoDB 文档来确认。
var params = {
TableName: table,
Key: {
"id": customerID,
},
UpdateExpression: "set customer_name= :s, customer_address= :p, customer_phone= :u, end_date = :u",
ExpressionAttributeValues: {
":s": customer_name,
":p": customer_address,
":u": customer_phone
},
ReturnValues: "UPDATED_NEW"
};
await docClient.update(params).promise();
事实证明,像 .contains(text)
这样的调用被用作 过滤器 ,而不是查询参数。 DynamoDB 在不查看每条记录的情况下无法确定索引中的文本是否包含我正在搜索的文本,这是扫描,而不是查询。因此,在这种情况下尝试使用 .contains(text)
没有任何意义,即使可以像我构建的那样在链中调用它。为了完成这项工作,我最终需要做的是将我的调用转换为使用 .contains(text)
过滤器的 table 扫描:
Users.scan({ email: { contains: query.email }}).all().exec().then( ... )