英文:
DynamoDB Query with equality on PK and Begins with on SK in Go using Expressions package
问题
我正在尝试使用Go语言在DynamoDB表上编写一个查询操作。我想复制以下CLI命令:
aws dynamodb query \
--table-name myTable \
--index-name name-index \
--key-condition-expression "_pk = :dpid and begins_with(st, :st)" \
--expression-attribute-values '{"dpid":{"S":"dp#1"}, "st":{"S":"jam"}}'
注意 _pk
前面的下划线。
我尝试使用 Expressions package,但是我觉得文档非常令人困惑。到目前为止,我有以下代码:
func (p *PatientStore) SearchPatients(ctx context.Context, searchTerm string) ([]PatientSearchResponseItem, error) {
dentalPracticeId := "dp#1"
lowerCaseSearchTerm := strings.ToLower(searchTerm)
var err error
var response *dynamodb.QueryOutput
var patients []PatientSearchResponseItem
keyEx := expression.Key("_pk").Equal(expression.Value(dentalPracticeId))
gsiCondition := expression.BeginsWith(expression.Name("st"), lowerCaseSearchTerm) // gsiCondition declared but not used error
expr, err := expression.NewBuilder().WithKeyCondition(keyEx).Build()
if err != nil {
log.Printf("Couldn't build expression for query. Here's why: %v\n", err)
} else {
response, err = p.client.Query(context.TODO(), &dynamodb.QueryInput{
TableName: aws.String(p.tableName),
IndexName: jsii.String("name-index"),
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
KeyConditionExpression: expr.KeyCondition(),
})
if err != nil {
log.Printf("Couldn't query for patients matching %v. Here's why: %v\n", lowerCaseSearchTerm, err)
} else {
err = attributevalue.UnmarshalListOfMaps(response.Items, &patients)
if err != nil {
log.Printf("Couldn't unmarshal query response. Here's why: %v\n", err)
}
}
}
return patients, err
}
目前,我收到一个错误,指出 gsiCondition
被声明但未使用,这是有道理的,但我不知道如何使用该条件。文档中没有显示如何使用多个条件。
我该如何使其工作起来?
英文:
I am trying to write a Query operation on a DynamoDB table with Go. I am trying to duplicate the following CLI command:
aws dynamodb query \
--table-name myTable \
--index-name name-index \
--key-condition-expression "_pk = :dpid and begins_with(st, :st)" \
--expression-attribute-values '{":dpid":{"S":"dp#1"}, ":st":{"S":"jam"}}'
Note the _
in front of the _pk
.
I am trying to use the Expressions package, but I find the docs super confusing. So far I have:
func (p *PatientStore) SearchPatients(ctx context.Context, searchTerm string) ([]PatientSearchResponseItem, error) {
dentalPracticeId := "dp#1"
lowerCaseSearchTerm := strings.ToLower(searchTerm)
var err error
var response *dynamodb.QueryOutput
var patients []PatientSearchResponseItem
keyEx := expression.Key("_pk").Equal(expression.Value(dentalPracticeId))
gsiCondition := expression.BeginsWith(expression.Name("st"), lowerCaseSearchTerm) // gsiCondition declared but not used error
expr, err := expression.NewBuilder().WithKeyCondition(keyEx).Build()
if err != nil {
log.Printf("Couldn't build epxression for query. Here's why: %v\n", err)
} else {
response, err = p.client.Query(context.TODO(), &dynamodb.QueryInput{
TableName: aws.String(p.tableName),
IndexName: jsii.String("name-index"),
ExpressionAttributeNames: expr.Names(),
ExpressionAttributeValues: expr.Values(),
KeyConditionExpression: expr.KeyCondition(),
})
if err != nil {
log.Printf("Couldn't query for patients matching %v. Here's why: %v\n", lowerCaseSearchTerm, err)
} else {
err = attributevalue.UnmarshalListOfMaps(response.Items, &patients)
if err != nil {
log.Printf("Couldn't unmarshal query response. Here's why: %v\n", err)
}
}
}
return patients, err
}
Right now, I'm getting an error that states that the gsiCondition is declared but not used
, which makes sense, but I don't know how to use that condition. The docs don't show how to have multiple conditions.
How can I get this working?
答案1
得分: 1
你看过我们在GitHub上的示例了吗?
这应该会给你所需的信息。
至于异常,如果你不需要请求中的expressionAttributeValues/Names,你可以简单地省略它们。
package main
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
func main() {
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = "eu-west-1"
return nil
})
if err != nil {
panic(err)
}
svc := dynamodb.NewFromConfig(cfg)
out, err := svc.Query(context.TODO(), &dynamodb.QueryInput{
TableName: aws.String("test"),
KeyConditionExpression: aws.String("#pk = :pk and #sk > :sk"),
ExpressionAttributeValues: map[string]types.AttributeValue{
":pk": &types.AttributeValueMemberS{Value: "lhnng"},
":sk": &types.AttributeValueMemberN{Value: "500"},
},
ExpressionAttributeNames: map[string]string{
"#pk": "_pk",
"#sk": "sk",
},
})
if err != nil {
panic(err)
}
fmt.Println(out.Items)
}
英文:
Have you taken a look at our examples on GitHub?
This should give you the information you require.
As for the exception, you cannot declare expressionAttributeValues/Names and not use them, it they are no needed for the request you can simply omit them.
package main
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
func main() {
cfg, err := config.LoadDefaultConfig(context.TODO(), func(o *config.LoadOptions) error {
o.Region = "eu-west-1"
return nil
})
if err != nil {
panic(err)
}
svc := dynamodb.NewFromConfig(cfg)
out, err := svc.Query(context.TODO(), &dynamodb.QueryInput{
TableName: aws.String("test"),
KeyConditionExpression: aws.String("#pk = :pk and #sk > :sk"),
ExpressionAttributeValues: map[string]types.AttributeValue{
":pk": &types.AttributeValueMemberS{Value: "lhnng"},
":sk": &types.AttributeValueMemberN{Value: "500"},
},
ExpressionAttributeNames: map[string]string{
"#pk": "_pk",
"#sk": "sk",
},
})
if err != nil {
panic(err)
}
fmt.Println(out.Items)
}
答案2
得分: 0
将这段代码翻译为中文如下:
为了让其他人受益,我将这段代码放在这里。我使用表达式解决了这个问题。
var condition = expression.Name("pk").Equal(expression.Value("pkValue")).And(expression.Name("sk").BeginsWith("skValue"))
condExp, err := expression.NewBuilder().WithCondition(condition).Build()
if err != nil {
return nil, fmt.Errorf("构建表达式时出错:%w", err)
}
response, err := svc.Query(c, &dynamodb.QueryInput{
TableName: &tableName,
KeyConditionExpression: condExp.Condition(),
ExpressionAttributeNames: condExp.Names(),
ExpressionAttributeValues: condExp.Values(),
})
if err != nil {
return nil, fmt.Errorf("读取数据失败:%w", err)
}
英文:
Putting this here just for the benefit of others. I was able to solve it with expressions
var condition = expression.Name("pk").Equal(expression.Value("pkValue")).And(expression.Name("sk").BeginsWith("skValue"))
condExp, err := expression.NewBuilder().WithCondition(condition).Build()
if err != nil {
return nil, fmt.Errorf("error building expression: %w", err)
}
response, err := svc.Query(c, &dynamodb.QueryInput{
TableName: &tableName,
KeyConditionExpression: condExp.Condition(),
ExpressionAttributeNames: condExp.Names(),
ExpressionAttributeValues: condExp.Values(),
})
if err != nil {
return nil, fmt.Errorf("failed reading data: %w", err)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论