V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mentalidade
V2EX  ›  程序员

golang 怎么转化这个 struct?

  •  
  •   mentalidade · 2017-11-15 17:21:24 +08:00 · 5035 次点击
    这是一个创建于 2567 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请求 elk 的 post 参数是这个 json,两个 term,不同的 value,不知道是我写的这个结构体的有问题还是初始化有问题。求解怎么初始化?

    • 原始 json
    {
        "_source": {
            "excludes": [
                "offset",
                "*type",
                "beat",
                "*timestamp"
            ]
        },
        "query": {
            "bool": {
                "filter": [
                    {
                        "term": {
                            "loglvl.keyword": "ERROR"
                        }
                    },
                    {
                        "term": {
                            "module": "demo"
                        }
                    },
                    {
                        "range": {
                            "logtime": {
                                "gte": "2017-10-20T09:45:35.015+0800",
                                "lte": "2017-10-24T09:45:35.015+0800"
                            }
                        }
                    }
                ]
            }
        }
    }
    
    • 定义的结构体
    type RequestValue struct {
    	Source struct {
    		Excludes []string `json:"excludes"`
    	} `json:"_source"`
    	Query struct {
    		Bool struct {
    			Filter []struct {
    				Term struct {
    					LoglvlKeyword string `json:"loglvl.keyword,omitempty"`
    					Module string `json:"module,omitempty"`
    				} `json:"term,omitempty"`
    				Range struct {
    					Logtime struct {
    						Gte string `json:"gte"`
    						Lte string `json:"lte"`
    					} `json:"logtime"`
    				} `json:"range,omitempty"`
    			} `json:"filter"`
    		} `json:"bool"`
    	} `json:"query"`
    }
    

    我这么初始化,想写一个当前时间的 Gte 的 value。

    	model.RequestValue{
    		Source: {
    			Excludes: {"offset", "*type", "beat", "*timestamp"}
    		},
    		Query: {
    			Bool: {
    				Filter: {
    					{Term: {LoglvlKeyword: "ERROR"}},
    					{Term: {Module: "demo"}},
    					{Range: {Logtime: {Gte: "2017-10-20T09:45:35.015+0800",
    						Lte: "2017-10-24T09:45:35.015+0800"
    					},},}
    				},
    			},
    		},
    	}
    
    34 条回复    2018-09-02 11:51:48 +08:00
    janxin
        1
    janxin  
       2017-11-15 17:29:25 +08:00
    编译错误不是有么?没有指定类型
    zrelda
        2
    zrelda  
       2017-11-15 17:31:29 +08:00
    json.RawMessage
    shawngao
        3
    shawngao  
       2017-11-15 17:33:36 +08:00
    type AutoGenerated struct {
    Source struct {
    Excludes []string `json:"excludes"`
    } `json:"_source"`
    Query struct {
    Bool struct {
    Filter []struct {
    Term struct {
    LoglvlKeyword string `json:"loglvl.keyword"`
    } `json:"term,omitempty"`
    Range struct {
    Logtime struct {
    Gte string `json:"gte"`
    Lte string `json:"lte"`
    } `json:"logtime"`
    } `json:"range,omitempty"`
    } `json:"filter"`
    } `json:"bool"`
    } `json:"query"`
    }
    mentalidade
        4
    mentalidade  
    OP
       2017-11-15 17:41:41 +08:00
    @shawngao https://mholt.github.io/json-to-go/ 这个生成的丢失了第二个 term,第二个是 module
    mason961125
        5
    mason961125  
       2017-11-15 17:43:05 +08:00
    我觉得你可能需要 https://github.com/buger/jsonparser
    mason961125
        6
    mason961125  
       2017-11-15 17:43:43 +08:00
    哦,我以为是解析,当我没说
    mentalidade
        7
    mentalidade  
    OP
       2017-11-15 17:45:35 +08:00
    @zrelda v 站大神真的多,这个强
    mentalidade
        8
    mentalidade  
    OP
       2017-11-15 17:46:29 +08:00
    @mason961125 我是要编码,实在太深而且复杂
    mason961125
        9
    mason961125  
       2017-11-15 17:50:49 +08:00
    @mentalidade Go 处理 JSON 麻烦也不是一天两天了,只能忍着...
    loading
        10
    loading  
       2017-11-15 17:52:43 +08:00 via Android
    golang 除了 err nil,我最讨厌就是结构体了
    Morriaty
        11
    Morriaty  
       2017-11-15 18:19:07 +08:00
    你为什么要自己定义 struct query,而不是 interface{}?

    尤其是 es 本身的 query 参数就 N 多的,你枚举都枚举不完,难道你要每种 query 都建一个 struct ?
    mentalidade
        12
    mentalidade  
    OP
       2017-11-15 18:44:43 +08:00
    @Morriaty 其他的参数都不变的,就是这个时间换一下。需求多了,es 的 json 解开就痛苦无比了,求教
    mentalidade
        13
    mentalidade  
    OP
       2017-11-15 19:00:02 +08:00
    @janxin 明白了,嵌套的结构体没有在外面定义没法确定类型
    owenliang
        14
    owenliang  
       2017-11-15 19:02:42 +08:00
    解 json 会让人想死,最后走 unmarshal 直接反解到某个结构体。
    mentalidade
        15
    mentalidade  
    OP
       2017-11-15 19:41:08 +08:00
    @owenliang es 请求体里面的一个 json 体 body,搞的吐血,格式一变化就得另外在定义一个多层嵌套的结构体,
    mentalidade
        16
    mentalidade  
    OP
       2017-11-15 19:42:27 +08:00
    @mentalidade 光上面一个 filter 里面两个一模一样还不能合并的 term,就搞得我晕死,心态爆照
    jameshuazhou
        17
    jameshuazhou  
       2017-11-15 19:46:15 +08:00
    用 map[string]interface{},一层层套下去
    jameshuazhou
        18
    jameshuazhou  
       2017-11-15 19:51:21 +08:00
    type RMap map[string]interface{}

    req := RMap{
    "filter": []RMap{
    {"term": RMap{"loglvl.keyword": "ERROR"}},
    {"term": RMap{"module": "demo"}},
    }
    }
    mentalidade
        19
    mentalidade  
    OP
       2017-11-15 20:28:23 +08:00 via Android
    @jameshuazhou 多谢,我试试
    shawngao
        20
    shawngao  
       2017-11-15 20:54:34 +08:00
    @mentalidade 没细看,gjson 也不能满足你的要求么?
    shawngao
        21
    shawngao  
       2017-11-15 20:57:40 +08:00
    "query.bool.filter.1.term.module" >> "demo"
    没测,试试?
    mentalidade
        22
    mentalidade  
    OP
       2017-11-16 00:31:09 +08:00
    @jameshuazhou 感谢,这个方法可以的
    mentalidade
        23
    mentalidade  
    OP
       2017-11-16 00:31:59 +08:00
    @shawngao 感谢,我用了楼上的方法,可以了
    mnhkahn
        24
    mnhkahn  
       2017-11-16 09:14:26 +08:00
    es 的包都封装了这些,直接找个包方便些吧。自己写的话 filter 定义成一个接口,term、range 这些都实现 interface 就可以了。
    mengzhuo
        25
    mengzhuo  
       2017-11-16 09:30:58 +08:00 via iPhone
    好好用 elastic 驱动啊
    自己写也要用 json-to-go 啊
    mentalidade
        26
    mentalidade  
    OP
       2017-11-16 09:37:47 +08:00
    @mnhkahn 求问有 go 的包吗?
    mentalidade
        27
    mentalidade  
    OP
       2017-11-16 09:38:53 +08:00
    @mengzhuo 请问什么驱动?我就是用这个 json-to-go 转化的时候,它把 filter 里面第二个 term 过滤掉了,只有第一个
    mnhkahn
        28
    mnhkahn  
       2017-11-16 09:41:00 +08:00
    mentalidade
        29
    mentalidade  
    OP
       2017-11-16 10:08:25 +08:00
    @mnhkahn 好,谢谢
    mengzhuo
        30
    mengzhuo  
       2017-11-16 10:11:42 +08:00
    bomb77
        31
    bomb77  
       2018-01-12 12:16:50 +08:00
    不知道楼主对生成这种复杂嵌套 json 有什么其他好的办法了吗?
    用 17 楼的办法是拼出来了,可以还是感觉有些麻烦,和 go 里的 struct 不太相符
    mentalidade
        32
    mentalidade  
    OP
       2018-01-12 13:34:38 +08:00
    @bomb77 如果是定时脚本,以后不怎么变化的话自己解开,用 17 楼方法就好。如果经常变化的话,那就用 28 的库,直接拼装,解开可以用 fastjson 貌似,好处理一下
    bomb77
        33
    bomb77  
       2018-01-12 13:52:51 +08:00
    @mentalidade 谢谢回复,看来暂时还是用 map 手动拼吧,写分离的静态 struct 实在太麻烦了
    WilliamYang
        34
    WilliamYang  
       2018-09-02 11:51:48 +08:00
    说一个关于处理这种大型 json 的比较好的办法, 如果 json 结构比较固定, 可以写成模板, 传入参数, 再生成 json
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1062 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:18 · PVG 03:18 · LAX 11:18 · JFK 14:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.