如何处理文档中不一致的 JSON 字段

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

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)
	}
}

huangapple
  • 本文由 发表于 2015年11月1日 16:51:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/33460559.html
匿名

发表评论

匿名网友

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

确定