如何检索嵌套的地图值

时间:2016-09-03 14:31:47

标签: go

我想扫描AWS DynamoDB表,然后只提取某个值。这是我的代码:

package main

import (
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/dynamodb"
)

func main() {
    svc := dynamodb.New(session.New(), &aws.Config{Region: aws.String("us-west-2")})

    params := &dynamodb.ScanInput{
        TableName: aws.String("my_Dynamo_table_name"),
        Limit: aws.Int64(2),
    }

    resp, err := svc.Scan(params)
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    fmt.Println(resp)
}

,输出为:

{
  Count: 2,
  Items: [{
      update_time: {
        N: "1466495096"
      },
      create_time: {
        N: "1465655549"
      }
    },{
      update_time: {
        N: "1466503947"
      },
      create_time: {
        N: "1466503947"
      }
    }],
  LastEvaluatedKey: {
    Prim_key: {
      S: "1234567890"
    }
  },
  ScannedCount: 2
}

现在,我想检索上面输出中所有元素的update_time值。以下是我的尝试:

for _, value := range resp.Items {
    fmt.Println(value["create_time"]["N"])
}

for _, value := range resp.Items {
    fmt.Println(value.create_time.N)
}

for _, value := range resp.Items {
    fmt.Println(*value.create_time.N)
}

以上所有尝试都会因/var/tmp/dynamo.go:37: invalid operation:错误而出错。 我来自perl / python背景,最近开始学习golang。

在这种情况下如何检索嵌套的地图/数组值。此外,任何阅读参考将有很大帮助。我的谷歌搜索没有透露任何相关内容。

2 个答案:

答案 0 :(得分:1)

上面resp的值属于*ScanOutput类型,Items类型为[]map[string]*AttributeValue

要访问update_time,您可以尝试:

updateTimes := make([]string, 0)

// Items is a slice of map of type map[string]*AttributeValue
for _, m := range resp.Items {
    // m is of type map[string]*AttributeValue
    timeStrPtr := *m["update_time"].N
    updateTimes = append(updateTimes, *timeStrPtr)
}

updateTimes现在应该包含所有"update_time"值作为字符串。

更多详情here

答案 1 :(得分:0)

您应该使用dynamodbattribute包。它更便宜,更安全,更易读。

按照你的例子:

type Row struct {
    CreateTime int `dynamodbav:"create_time"`  
    UpdateTime int `dynamodbav:"update_time"` 
}

// ...
rows := make([]*Row, len(resp.Items))
if err := dynamodbattribute.Unmarshal(resp.Items, &rows); err != nil {
    // handle the error    
}

// access the data
for _, row := range rows {
    fmt.Println(row.CreateTime, row.UpdateTime)    
}