英文:
how to deal with inconsistent json fields in documents
问题
我目前有一个大的JSON文件,需要存储在后端(mongodb和Go)并在前端中使用。我想知道文档的第三个字段是否应该是"子类别",而不是第二个字段中的运动名称,或者是否可能这样做,因为我认为这可能在后端语言中建模和反序列化时很难处理不一致性。
示例:
{
"_id" : ObjectId("55c"),
"Sport" : "田径",
"Athletics" : {
["男子个人", "女子个人", "混合接力"]
}
}
{
"_id" : ObjectId("56c"),
"Sport" : "网球",
"Tennis" : ["男子单打", "女子单打", "男子双打", "女子双打", "混合双打"]
}
{
"_id" : ObjectId("57c"),
"Sport" : "游泳",
"Swimming" : {
"男子" : ["4×100米接力", "4×200米自由泳接力"],
"女子" : ["4×100米接力", "4×200米自由泳接力"]
}
}
英文:
I currently have a large JSON file which has to be stored in the backend (mongodb & Go) and consumed in the front end. I was wondering whether the 3rd field of the documents should be something like "Sub category" instead of the sport name from the 2nd field or whether this is possible as I was thinking this maybe hard to model and deserialise in a backend language due to inconsistency?
sample:
{
"_id" : ObjectId("55c"),
"Sport" : "Athletics ",
"Athletics" : {
["Men's Individual", "Women's Individual", "Mixed Relay"]
}
}
{
"_id" : ObjectId("56c"),
"Sport" : "Tennis",
"Tennis" : ["Men's singles", "Women's singles", "Men's doubles", "Women's doubles", "Mixed doubles"]
}
{
"_id" : ObjectId("57c"),
"Sport" : "Swimming",
"Swimming" : {
"Men" : ["4×100 m relay", "4×200 m freestyle relay"],
"Women" : ["4×100 m relay", "4×200 m freestyle relay"]
}
}
答案1
得分: 3
我同意那个小声音告诉你选择“子类别”而不是试图处理不一致的类型。此外,你应该像在网球和田径项目中那样将“男子”和“女子”子类别合并到游泳项目中。这将使你更好地利用encoding/json(和mgo/bson)的映射功能,但我不认为这是一个“后端语言”的问题 - 一致的数据类型也应该使你的js(和其他客户端代码)更加友好!
英文:
I'd agree with the little voice telling you to go with "Sub-Category" instead of trying to deal with inconsistent types. Also, you should combine the 'mens' and 'womens' subcategories in Swimming similar to how you do it it in Tennis and Athletics. This will let you make better use of encoding/json's (and mgo/bson's) mapping features, but I wouldn't call it a 'backend language' problem - consistent data types should make your js (and other client code) nicer, too!
答案2
得分: 2
你可以使用json.RawMessage
来实现这个功能:
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
type Color struct {
Space string
Point json.RawMessage // 延迟解析,直到我们知道颜色空间
}
type RGB struct {
R uint8
G uint8
B uint8
}
type YCbCr struct {
Y uint8
Cb int8
Cr int8
}
var j = []byte(`[
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}}
]`)
var colors []Color
err := json.Unmarshal(j, &colors)
if err != nil {
log.Fatalln("error:", err)
}
for _, c := range colors {
var dst interface{}
switch c.Space {
case "RGB":
dst = new(RGB)
case "YCbCr":
dst = new(YCbCr)
}
err := json.Unmarshal(c.Point, dst)
if err != nil {
log.Fatalln("error:", err)
}
fmt.Println(c.Space, dst)
}
}
英文:
You can do that using json.RawMessage
:
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
type Color struct {
Space string
Point json.RawMessage // delay parsing until we know the color space
}
type RGB struct {
R uint8
G uint8
B uint8
}
type YCbCr struct {
Y uint8
Cb int8
Cr int8
}
var j = []byte(`[
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}}
]`)
var colors []Color
err := json.Unmarshal(j, &colors)
if err != nil {
log.Fatalln("error:", err)
}
for _, c := range colors {
var dst interface{}
switch c.Space {
case "RGB":
dst = new(RGB)
case "YCbCr":
dst = new(YCbCr)
}
err := json.Unmarshal(c.Point, dst)
if err != nil {
log.Fatalln("error:", err)
}
fmt.Println(c.Space, dst)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论