Home  >  Article  >  Backend Development  >  How to Unmarshall Nested JSON with Unknown Structure Efficiently?

How to Unmarshall Nested JSON with Unknown Structure Efficiently?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-04 05:02:29410browse

How to Unmarshall Nested JSON with Unknown Structure Efficiently?

Unmarshalling Nested JSON with Unknown Structure

In this scenario, we are dealing with JSON data with an unknown structure stored in a key-value store. When retrieving entries from the database, we initially unmarshal into a map[string]*json.RawMessage to handle the top-level namespace. However, to further unmarshal the nested data, we need to determine the specific struct to use.

1. Avoiding Repeated Unmarshals:

Repeated unmarshals can potentially affect performance. However, it may be necessary depending on the data structure and access patterns. If unmarshalling speed is critical, consider caching the unmarshalled results.

2. Determining Struct Type:

Method A: Unmarshal to Interface

  • Unmarshal the json.RawMessage to a map[string]interface{}.
  • Check the value associated with the "type" key.
  • Use a switch statement or reflection to determine the correct struct.

Method B: Regular Expression

  • Use a regular expression to extract the "type" string from the JSON data.
  • Create a map of struct types associated with the possible "type" strings.
  • Unmarshal the json.RawMessage to the corresponding struct.

Example:

Method A:

<code class="go">type RawData struct {
    Id       string `json:"id"`
    Type      string `json:"type"`
    RawData   []int  `json:"rawdata"`
    Epoch     string `json:"epoch"`
}

// Unmarshal to interface
data := make(map[string]interface{})
json.Unmarshal(*objmap["foo"], &data)

// Determine struct type
switch data["type"] {
case "baz":
    baz := &RawData{}
    json.Unmarshal(*objmap["foo"], baz)
case "bar":
    bar := &BarData{}
    json.Unmarshal(*objmap["foo"], bar)
}

// Custom struct for nested data
type BarData struct {
    Id       string `json:"id"`
    Type      string `json:"type"`
    RawData   []QuxData  `json:"rawdata"`
    Epoch     string `json:"epoch"`
}

type QuxData struct{
    Key string `json:"key"`
    Values []int `json:"values`
}</code>

Method B:

<code class="go">// Regular expression to extract type
typeRegex := regexp.MustCompile(`"type": "(.+?)"`)

// Get "type" string
typeString := string(typeRegex.Find(*objmap["foo"]))

// Map of struct types
structMap := map[string]interface{}{
    "baz": &RawData{},
    "bar": &BarData{},
}

// Unmarshal to corresponding struct
dataStruct := structMap[typeString]
json.Unmarshal(*objmap["foo"], dataStruct)</code>

By implementing either of these methods, you can determine the correct struct to unmarshal the json.RawMessage into, enabling you to access the nested data efficiently.

The above is the detailed content of How to Unmarshall Nested JSON with Unknown Structure Efficiently?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn