如何在Golang中创建嵌套数据集的结构?

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

How to create structure for nested data set in golang?

问题

新手学习golang,尝试编写一个脚本来批量上传到Elasticsearch服务器。我的JSON数据集如下所示...

{
    "product_displayname": "LG Stylus 2 Plus K535D (16 GB, Brown)",
    "product_price": "24000.00",
    "popularity": "0.00",
    "barcode": "",
    "exclusive_flag": "0",
    "product_id": "176982",
    "product_name": "Stylus 2 Plus K535D (Brown)",
    "brand_name": "LG",
    "brand_id": "1",
    "product_spec": {
        "display_spec": [
            {
                "spec_id": "103",
                "sdv": "24000",
                "snv": "24000.0000"
            },
            {
                "spec_id": "104",
                "sdv": "GSM",
                "snv": "0.0000"
            }
        ],
        "filter_spec": [
            {
                "spec_id": "103",
                "sdv": "24000",
                "snv": "24000.0000"
            },
            {
                "spec_id": "105",
                "sdv": "Touch Screen",
                "snv": "0.0000"
            }
        ]
    }
}

我根据谷歌和其他在线信息创建了以下的Golang结构体来表示上述数据集:

type Product struct {
    ProductDisplayname string `json:"product_displayname"`
    ProductPrice       string `json:"product_price"`
    Popularity         string `json:"popularity"`
    Barcode            string `json:"barcode"`
    ExclusiveFlag      string `json:"exclusive_flag"`
    ProductID          string `json:"product_id"`
    ProductName        string `json:"product_name"`
    BrandName          string `json:"brand_name"`
    BrandID            string `json:"brand_id"`
    ProductSpec        struct {
        DisplaySpec []struct {
            SpecID string `json:"spec_id"`
            Sdv    string `json:"sdv"`
            Snv    string `json:"snv"`
        } `json:"display_spec"`
        FilterSpec []struct {
            SpecID string `json:"spec_id"`
            Sdv    string `json:"sdv"`
            Snv    string `json:"snv"`
        } `json:"filter_spec"`
    } `json:"product_spec"`
}

但是,当我尝试在我的批量上传脚本中使用上述结构体和示例数据时,我遇到了以下错误:

github.com/crazyheart/elastic-bulk-upload/main.go:70: syntax error: missing operand
github.com/crazyheart/elastic-bulk-upload/main.go:70: unknown escape sequence
github.com/crazyheart/elastic-bulk-upload/main.go:71: syntax error: non-declaration statement outside function body

我觉得我在映射Golang结构体中的嵌套字段display_specfilter_spec时犯了一些错误,但是我无法找出问题所在。

你可以参考以下的main.go代码:

package main

import (
    "fmt"
    "golang.org/x/net/context"
    "gopkg.in/olivere/elastic.v5"
    "strconv"
)

type Product struct {
    ProductDisplayname string `json:"product_displayname"`
    ProductPrice       string `json:"product_price"`
    Popularity         string `json:"popularity"`
    Barcode            string `json:"barcode"`
    ExclusiveFlag      string `json:"exclusive_flag"`
    ProductID          string `json:"product_id"`
    ProductName        string `json:"product_name"`
    BrandName          string `json:"brand_name"`
    BrandID            string `json:"brand_id"`
    ProductSpec        struct {
        DisplaySpec []struct {
            SpecID string `json:"spec_id"`
            Sdv    string `json:"sdv"`
            Snv    string `json:"snv"`
        } `json:"display_spec"`
        FilterSpec []struct {
            SpecID string `json:"spec_id"`
            Sdv    string `json:"sdv"`
            Snv    string `json:"snv"`
        } `json:"filter_spec"`
    } `json:"product_spec"`
}

func main() {
    // 创建一个上下文
    ctx := context.Background()

    client, err := elastic.NewClient()
    if err != nil {
        fmt.Println("%v", err)
    }

    // 批量上传代码
    n := 0
    for i := 0; i < 1000; i++ {
        bulkRequest := client.Bulk()
        for j := 0; j < 10000; j++ {
            n++
            product_data := Product{
                ProductDisplayname: "LG Stylus 2 Plus K535D (16 GB, Brown)",
                ProductPrice:       "24000.00",
                Popularity:         "0.00",
                Barcode:            "",
                ExclusiveFlag:      "0",
                ProductID:          "17698276",
                ProductName:        "Stylus 2 Plus K535D (Brown)",
                BrandName:          "LG",
                BrandID:            "1",
                ProductSpec: struct {
                    DisplaySpec []struct {
                        SpecID string `json:"spec_id"`
                        Sdv    string `json:"sdv"`
                        Snv    string `json:"snv"`
                    } `json:"display_spec"`
                    FilterSpec []struct {
                        SpecID string `json:"spec_id"`
                        Sdv    string `json:"sdv"`
                        Snv    string `json:"snv"`
                    } `json:"filter_spec"`
                }{
                    DisplaySpec: []struct {
                        SpecID string `json:"spec_id"`
                        Sdv    string `json:"sdv"`
                        Snv    string `json:"snv"`
                    }{
                        {
                            SpecID: "103",
                            Sdv:    "24000",
                            Snv:    "24000.0000",
                        },
                        {
                            SpecID: "104",
                            Sdv:    "GSM",
                            Snv:    "0.0000",
                        },
                    },
                    FilterSpec: []struct {
                        SpecID string `json:"spec_id"`
                        Sdv    string `json:"sdv"`
                        Snv    string `json:"snv"`
                    }{
                        {
                            SpecID: "103",
                            Sdv:    "24000",
                            Snv:    "24000.0000",
                        },
                        {
                            SpecID: "105",
                            Sdv:    "Touch Screen",
                            Snv:    "0.0000",
                        },
                    },
                },
            }
            req := elastic.NewBulkIndexRequest().Index("shopfront").Type("products").Id(strconv.Itoa(n)).Doc(product_data)
            bulkRequest = bulkRequest.Add(req)
        }

        bulkResponse, err := bulkRequest.Do(ctx)
        if err != nil {
            fmt.Println(err)
        }
        if bulkResponse != nil {
            fmt.Println(bulkResponse)
        }
        fmt.Println(i)
    }
}

希望这可以帮助到你解决问题。

英文:

New to golang & trying to make a script for making bulk upload to Elasticsearch server. My json data set is something like this...

{
product_displayname: &quot;LG Stylus 2 Plus K535D (16 GB, Brown)&quot;,
product_price: &quot;24000.00&quot;,
popularity: &quot;0.00&quot;,
barcode: &quot;&quot;,
exclusive_flag: &quot;0&quot;,
product_id: &quot;176982&quot;,
product_name: &quot;Stylus 2 Plus K535D (Brown)&quot;,
brand_name: &quot;LG&quot;,
brand_id: &quot;1&quot;,
product_spec : {
display_spec: [{
spec_id: &quot;103&quot;,
sdv: &quot;24000&quot;,
snv: &quot;24000.0000&quot;
}, {
spec_id: &quot;104&quot;,
sdv: &quot;GSM&quot;,
snv: &quot;0.0000&quot;
}],
filter_spec: [{
spec_id: &quot;103&quot;,
sdv: &quot;24000&quot;,
snv: &quot;24000.0000&quot;
}, {
spec_id: &quot;105&quot;,
sdv: &quot;Touch Screen&quot;,
snv: &quot;0.0000&quot;
}]
}
}

Golang Structure I made(by refering google & other online info) for the above dataset is like this...

type Product struct {
product_displayname string `json:&quot;product_displayname&quot;`
product_price       string `json:&quot;product_price&quot;`
popularity          string `json:&quot;popularity&quot;`
barcode             string `json:&quot;barcode&quot;`
exclusive_flag      string `json:&quot;exclusive_flag&quot;`
product_id          string `json:&quot;product_id&quot;`
product_name        string `json:&quot;product_name&quot;`
brand_name          string `json:&quot;brand_name&quot;`
brand_id            string `json:&quot;brand_id&quot;`
product_spec
}
type product_spec struct {
display_spec []display_speclist
filter_spec []filter_speclist
}
type display_speclist struct {
spec_id string `json:&quot;spec_id&quot;`
sdv     string `json:&quot;sdv&quot;`
snv     string `json:&quot;snv&quot;`
}
type filter_speclist struct {
spec_id string `json:&quot;spec_id&quot;`
sdv     string `json:&quot;sdv&quot;`
snv     string `json:&quot;snv&quot;`
}

But, whenever I'm trying to use above Structure with sample data in my bulk upload script I'm getting following error

github.com/crazyheart/elastic-bulk-upload/main.go:70: syntax error: missing operand
github.com/crazyheart/elastic-bulk-upload/main.go:70: unknown escape sequence
github.com/crazyheart/elastic-bulk-upload/main.go:71: syntax error: non-declaration statement outside function body

I feel like I'm making some mistake in mapping that nested field display_spec &amp; filter_spec in golang structure. But can't able to figure out what it is.

main.go

package main
import (
&quot;fmt&quot;
&quot;golang.org/x/net/context&quot;
&quot;gopkg.in/olivere/elastic.v5&quot;
&quot;strconv&quot;
)
type Product struct {
ProductDisplayname string `json:&quot;product_displayname&quot;`
ProductPrice string `json:&quot;product_price&quot;`
Popularity string `json:&quot;popularity&quot;`
Barcode string `json:&quot;barcode&quot;`
ExclusiveFlag string `json:&quot;exclusive_flag&quot;`
ProductID string `json:&quot;product_id&quot;`
ProductName string `json:&quot;product_name&quot;`
BrandName string `json:&quot;brand_name&quot;`
BrandID string `json:&quot;brand_id&quot;`
ProductSpec struct {
DisplaySpec []struct {
SpecID string `json:&quot;spec_id&quot;`
Sdv string `json:&quot;sdv&quot;`
Snv string `json:&quot;snv&quot;`
} `json:&quot;display_spec&quot;`
FilterSpec []struct {
SpecID string `json:&quot;spec_id&quot;`
Sdv string `json:&quot;sdv&quot;`
Snv string `json:&quot;snv&quot;`
} `json:&quot;filter_spec&quot;`
} `json:&quot;product_spec&quot;`
}
func main() {
// Create a context
ctx := context.Background()
client, err := elastic.NewClient()
if err != nil {
fmt.Println(&quot;%v&quot;, err)
}
// Bulk upload code
n := 0
for i := 0; i &lt; 1000; i++ {
bulkRequest := client.Bulk()
for j := 0; j &lt; 10000; j++ {
n++
product_data := Product{product_displayname:&quot;LG Stylus 2 Plus K535D (16 GB, Brown)&quot;,product_price:&quot;24000.00&quot;,popularity:&quot;0.00&quot;,barcode:&quot;&quot;,exclusive_flag:&quot;0&quot;,product_id:&quot;17698276&quot;,product_name:&quot;Stylus 2 Plus K535D (Brown)&quot;,brand_name:&quot;LG&quot;,brand_id:&quot;1&quot;,product_spec:{display_spec:[{spec_id:&quot;103&quot;,sdv:&quot;24000&quot;,snv:&quot;24000.0000&quot;},{spec_id:&quot;104&quot;,sdv:&quot;GSM&quot;,snv:&quot;0.0000&quot;}],filter_spec:[{spec_id:&quot;103&quot;,sdv:&quot;24000&quot;,snv:&quot;24000.0000&quot;},{spec_id:&quot;105&quot;,sdv:&quot;Touch Screen&quot;,snv:&quot;0.0000&quot;}]}	}
req := elastic.NewBulkIndexRequest().Index(&quot;shopfront&quot;).Type(&quot;products&quot;).Id(strconv.Itoa(n)).Doc(product_data)
bulkRequest = bulkRequest.Add(req)
}
bulkResponse, err := bulkRequest.Do(ctx)
if err != nil {
fmt.Println(err)
}
if bulkResponse != nil {
fmt.Println(bulkResponse)
}
fmt.Println(i)
}
}

答案1

得分: 1

工作流程

  1. 验证你的 JSON(你发布的那个是无效的)。

  2. 构建一个合适的 struct,你可以使用这个很好的工具来帮助你。

针对你的情况

structs 看起来没问题,除了你没有通过将字段的首字母大写来导出结构体字段(感谢 @ANisus)。

这个(缩短的)看起来更加“自然”。

type Product struct {
    ProductDisplayname string `json:"product_displayname"`
    ProductSpec struct {
        DisplaySpec []struct {
            SpecID string `json:"spec_id"`
            Sdv string `json:"sdv"`
            Snv string `json:"snv"`
        } `json:"display_spec"`
        FilterSpec []struct {
            SpecID string `json:"spec_id"`
            Sdv string `json:"sdv"`
            Snv string `json:"snv"`
        } `json:"filter_spec"`
    } `json:"product_spec"`
}
英文:

Workflow

1.- Validate your json (the one you posted is invalid).

2.- Build a proper struct, you can help yourself using this nice tool.

For your case

The structs appears to be fine except you're not exporting the struct fields by capitalizing the initial letter (Thanks @ANisus).

This (shorted) seems more natural.

type Product struct {
ProductDisplayname string `json:&quot;product_displayname&quot;`
ProductSpec struct {
DisplaySpec []struct {
SpecID string `json:&quot;spec_id&quot;`
Sdv string `json:&quot;sdv&quot;`
Snv string `json:&quot;snv&quot;`
} `json:&quot;display_spec&quot;`
FilterSpec []struct {
SpecID string `json:&quot;spec_id&quot;`
Sdv string `json:&quot;sdv&quot;`
Snv string `json:&quot;snv&quot;`
} `json:&quot;filter_spec&quot;`
} `json:&quot;product_spec&quot;`
}

huangapple
  • 本文由 发表于 2017年3月14日 18:04:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/42782901.html
匿名

发表评论

匿名网友

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

确定