从Golang中的嵌套动态键JSON获取数据

huangapple go评论74阅读模式
英文:

Get data from nested dynamic keys json in golang

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我刚开始学习Go语言,我正在尝试从下面的JSON结构中提取特定的键。

{
    "cluster_name": "escluster",
    "nodes": {
        "Sd2AvEXsswjTn6ErRYjg": {
            "timestamp": 1460624696217,
            "name": "master1",
            "transport_address": "10.0.0.1:9300",
            "host": "10.0.0.1:9300",
            "ip": [
                "10.0.0.1:9300",
                "NONE"
            ],
            "attributes": {
                "data": "false",
                "master": "true"
            },
            "os": {
                "timestamp": 1460624696217,
                "cpu_percent": 0,
                "load_average": 0,
                "mem": {
                    "total_in_bytes": 163987664,
                    "free_in_bytes": 136357264,
                    "used_in_bytes": 26629400,
                    "free_percent": 84,
                    "used_percent": 16
                },
                "swap": {
                    "total_in_bytes": 0,
                    "free_in_bytes": 0,
                    "used_in_bytes": 0
                }
            }
        },
        "yzabB-OaTfOqvgAELIMq1Q": {
            "timestamp": 1460624938213,
            "name": "data_1",
            "transport_address": "10.0.0.2:9300",
            "host": "10.0.0.2",
            "ip": [
                "10.0.0.2:9300",
                "NONE"
            ],
            "attributes": {
                "master": "false"
            },
            "os": {
                "timestamp": 1460624938213,
                "cpu_percent": 0,
                "load_average": 0.29,
                "mem": {
                    "total_in_bytes": 623840000,
                    "free_in_bytes": 4127648,
                    "used_in_bytes": 666012352,
                    "free_percent": 1,
                    "used_percent": 99
                },
                "swap": {
                    "total_in_bytes": 0,
                    "free_in_bytes": 0,
                    "used_in_bytes": 0
                }
            }
        },
        "q5CdgUF2TRewujr-0RPMgQ": {
            "timestamp": 1460624934417,
            "name": "master_0",
            "transport_address": "10.0.0.3:9300",
            "host": "10.0.0.2",
            "ip": [
                "10.0.0.3:9300",
                "NONE"
            ],
            "attributes": {
                "data": "false",
                "master": "true"
            },
            "os": {
                "timestamp": 1460624934417,
                "cpu_percent": 0,
                "load_average": 0,
                "mem": {
                    "total_in_bytes": 163898764,
                    "free_in_bytes": 139705616,
                    "used_in_bytes": 24194588,
                    "free_percent": 85,
                    "used_percent": 15
                },
                "swap": {
                    "total_in_bytes": 0,
                    "free_in_bytes": 0,
                    "used_in_bytes": 0
                }
            }
        }
    }
}

由于节点名称是动态的,我想要提取每个节点的"mem"字段。我找到了这个链接,可以提取数据,但它的键不是动态的。在Go语言中,我们该如何实现这个功能?

英文:

I am new to go , I am trying to extract specific key from the json structure as below.

{
"cluster_name": "escluster",
"nodes": {
"Sd2AvEXsswjTn6ErRYjg": {
"timestamp": 1460624696217,
"name": "master1",
"transport_address": "10.0.0.1:9300",
"host": "10.0.0.1:9300",
"ip": [
"10.0.0.1:9300",
"NONE"
],
"attributes": {
"data": "false",
"master": "true"
},
"os": {
"timestamp": 1460624696217,
"cpu_percent": 0,
"load_average": 0,
"mem": {
"total_in_bytes": 163987664,
"free_in_bytes": 136357264,
"used_in_bytes": 26629400,
"free_percent": 84,
"used_percent": 16
},
"swap": {
"total_in_bytes": 0,
"free_in_bytes": 0,
"used_in_bytes": 0
}
}
},
"yzabB-OaTfOqvgAELIMq1Q": {
"timestamp": 1460624938213,
"name": "data_1",
"transport_address": "10.0.0.2:9300",
"host": "10.0.0.2",
"ip": [
"10.0.0.2:9300",
"NONE"
],
"attributes": {
"master": "false"
},
"os": {
"timestamp": 1460624938213,
"cpu_percent": 0,
"load_average": 0.29,
"mem": {
"total_in_bytes": 623840000,
"free_in_bytes": 4127648,
"used_in_bytes": 666012352,
"free_percent": 1,
"used_percent": 99
},
"swap": {
"total_in_bytes": 0,
"free_in_bytes": 0,
"used_in_bytes": 0
}
}
},
"q5CdgUF2TRewujr-0RPMgQ": {
"timestamp": 1460624934417,
"name": "master_0",
"transport_address": "10.0.0.3:9300",
"host": "10.0.0.2",
"ip": [
"10.0.0.3:9300",
"NONE"
],
"attributes": {
"data": "false",
"master": "true"
},
"os": {
"timestamp": 1460624934417,
"cpu_percent": 0,
"load_average": 0,
"mem": {
"total_in_bytes": 163898764,
"free_in_bytes": 139705616,
"used_in_bytes": 24194588,
"free_percent": 85,
"used_percent": 15
},
"swap": {
"total_in_bytes": 0,
"free_in_bytes": 0,
"used_in_bytes": 0
}
}
}
}
}      

As the node names are dynamic, I would like to retrieve mem for each node. I found this to retrieve data but its not dynamic key. How can we do this in go.

答案1

得分: 4

学习如何在Go中处理数据的一个很好的参考资料是:http://blog.golang.org/json-and-go

关于你的问题,我觉得你的数据相对结构良好...我在下面的playground示例中提供了一个提取每个节点中mem部分的示例:

http://play.golang.org/p/0O5U-3N_tA

其中的关键是,任何被_明确定义_的内容都可以被编码为struct。动态的内容(例如节点名称)可以被编码为映射(maps)。两者可以任意混合在一起,例如:

type Node struct {
Timestamp        uint64            `json:timestamp`
Name             string            `json:name`
TransportAddress string            `json:transport_address`
Host             string            `json:host`
Ip               []string          `json:ip`
Attributes       map[string]string `json:attributes`
Os               *OsInfo           `json:os`
}
type Payload struct {
Name  string           `json:cluster_name`
Nodes map[string]*Node `json:nodes`
}

可以同时捕获节点的一般结构(通过struct定义)和它们动态索引的事实(通过节点存储在动态map中)。

解组后,处理数据提取内存信息就非常简单了:一路上都是已知的结构体和映射:

var p Payload
if err := json.Unmarshal([]byte(payload), &p); err != nil {
log.Fatal(err)
}
for k, node := range p.Nodes {
fmt.Printf("%s: %s\n", k, node.Os.Mem)
}

输出如下:

Sd2AvEXsswjTn6ErRYjg: map[total_in_bytes:%!s(uint64=163987664) free_in_bytes:%!s(uint64=136357264) used_in_bytes:%!s(uint64=26629400) free_percent:%!s(uint64=84) used_percent:%!s(uint64=16)]
yzabB-OaTfOqvgAELIMq1Q: map[used_percent:%!s(uint64=99) total_in_bytes:%!s(uint64=623840000) free_in_bytes:%!s(uint64=4127648) used_in_bytes:%!s(uint64=666012352) free_percent:%!s(uint64=1)]
q5CdgUF2TRewujr-0RPMgQ: map[total_in_bytes:%!s(uint64=163898764) free_in_bytes:%!s(uint64=139705616) used_in_bytes:%!s(uint64=24194588) free_percent:%!s(uint64=85) used_percent:%!s(uint64=15)]

(当然,你可以在提取/重新格式化数据后立即丢弃Payload对象)

英文:

A good reference to learn how to process data in Go: http://blog.golang.org/json-and-go

Regarding your problem it seems to me like your data is relatively well structured... I have set an example extracting the mem part of each node in the following playground example:

http://play.golang.org/p/0O5U-3N_tA

The gist of it is that whatever is strongly specified can be encoded as structs. What is dynamic (e.g. your node names) can be encoded as maps. Both can be arbitrarily intermingled, so that this:

type Node struct {
Timestamp        uint64            `json:timestamp`
Name             string            `json:name`
TransportAddress string            `json:transport_address`
Host             string            `json:host`
Ip               []string          `json:ip`
Attributes       map[string]string `json:attributes`
Os               *OsInfo           `json:os`
}
type Payload struct {
Name  string           `json:cluster_name`
Nodes map[string]*Node `json:nodes`
}

Can capture both the general structure of a node (via its struct definition) and the fact that they're dynamically indexed (via the fact that nodes themselves are stored in a dynamic map.

Once unmarshalled, it's then trivial to process your data to extract your memory info: it's just well-known structs and maps all the way down:

var p Payload
if err := json.Unmarshal([]byte(payload), &p); err != nil {
log.Fatal(err)
}
for k, node := range p.Nodes {
fmt.Printf("%s: %s\n", k, node.Os.Mem)
}

Outputs as expected:

Sd2AvEXsswjTn6ErRYjg: map[total_in_bytes:%!s(uint64=163987664) free_in_bytes:%!s(uint64=136357264) used_in_bytes:%!s(uint64=26629400) free_percent:%!s(uint64=84) used_percent:%!s(uint64=16)]
yzabB-OaTfOqvgAELIMq1Q: map[used_percent:%!s(uint64=99) total_in_bytes:%!s(uint64=623840000) free_in_bytes:%!s(uint64=4127648) used_in_bytes:%!s(uint64=666012352) free_percent:%!s(uint64=1)]
q5CdgUF2TRewujr-0RPMgQ: map[total_in_bytes:%!s(uint64=163898764) free_in_bytes:%!s(uint64=139705616) used_in_bytes:%!s(uint64=24194588) free_percent:%!s(uint64=85) used_percent:%!s(uint64=15)]

(You are of course free to extract/reformat your data first and ditch the Payload object as soon as this is complete)

huangapple
  • 本文由 发表于 2016年4月14日 17:17:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/36618679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定