I want to fetch url value i.e. hahaha from this interface (without using indexing) using Golang.
I want url from this interface using GOLANG
{
"data" : [
{
"key" : "xyz",
"val" : "ftghj"
},
{
"key" : "url",
"val" : "hahaha"
}
]
}
I tried this method, but here i have to use indexing
resbodyMap := make(map[string]interface{})
json.Unmarshal([]byte(data), &resbodyMap) // (here my data was in the byte format)`
data := resbodyMap["extendedData"]
Url := extData.([]interface{})[1]
mp := Url.(map[string]interface{})
url := mp["val"]
I want url from this interface using GOLANG
are you want like this?
package main
import (
"encoding/json"
"fmt"
)
var data = `{
"data" : [
{
"key" : "xyz",
"val" : "ftghj"
},
{
"key" : "url",
"val" : "hahaha"
}
]
}`
type KeyValue struct {
Val *string `json:"val"`
}
type Data struct {
Data []*KeyValue `json:"data"`
}
func main() {
var val string
json.Unmarshal([]byte(data), &Data{[]*KeyValue{nil, {&val}}})
fmt.Println(val)
}
However, it is not useful in actual use.
Related
I want get informations in JSON-RPC file with this structure :
{
"id": "foo1",
"error": null,
"result": [
{
"key": [
"hello 1",
1,
"world 1"
],
"val": {
"type": "static"
}
},
{
"key": [
"hello 2",
1,
"world 2"
],
"val": {
"type": "static"
}
}
]
}
This is my parsing function, Key is string table (can't accept int type) :
type JsonRpcRsp struct {
Id string `json:"id"`
Error *string `json:"error"`
Result json.RawMessage `json:"result"`
}
type JsonRpcEntry_Val struct {
Type string `json:"type"`
}
type JsonRpcEntry struct {
Key [3]string `json:"key"`
Val JsonRpcEntry_Val `json:"val"`
}
jsonResult := JsonRpcRsp{}
json.Unmarshal(data, &jsonResult)
entries := []JsonRpcEntry{}
for _, val := range jsonResult {
json.Unmarshal(val.Result, &entries)
}
How to parse "key" table ?... problem is there are different types
key table structure is :
[ <string>, <int>, <string>]
To unmarshal arrays of different types in Go you'll need to use interfaces and consequently type assertions if you need access to the types.
This will work for you:
type Result struct {
Key [3]interface{} `json:"key"`
Val struct {
Type string `json:"type"`
} `json:"val"`
}
msg := JsonRpcRsp{}
json.Unmarshal(data, &msg)
var result []Result
json.Unmarshal(msg.Result, &result)
for _, v := range result {
key1 := v.Key[0].(string)
key2 := v.Key[1].(float64)
key3 := v.Key[2].(string)
fmt.Println(key1, key2, key3)
}
After asserting the three interfaces to their types, you can then work with them further, depending on your use case.
I am running the below code. When a user saved in db then blank address is saved I have assigned the null struct to address before save. I can not add the omitempty with all the fields for address struct. How I can avoid to save blank address object within users collection
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type User struct {
Id int `json:"id" bson:"_id,omitempty"`
FirstName string `json:"first_name,omitempty" bson:"first_name,omitempty"`
LastName string `json:"last_name,omitempty" bson:"last_name,omitempty"`
FullName string `json:"full_name,omitempty" bson:"full_name,omitempty"`
CompanyName string `json:"company_name" bson:"company_name"`
Address AddressStruct `json:"address,omitempty" bson:"address,omitempty"`
}
type AddressStruct struct {
Address string `json:"address" bson:"address"`
City string `json:"city" bson:"city"`
State string `json:"state" bson:"state"`
Zipcode string `json:"zipcode" bson:"zipcode"`
Apt string `json:"apt" bson:"apt"`
Default bool `json:"default" bson:"default"`
Status int8 `json:"status,omitempty" bson:"status,omitempty"`
Country string `json:"country,omitempty" bson:"country,omitempty"`
ShortAddress string `json:"short_address" bson:"short_address"`
}
func main() {
var user User
user.FirstName = "Swati"
user.LastName = "Sharma"
user.FullName = "Swati Sharma"
user.Address = AddressStruct{}
client, ctx := ConnectDbWithNewDriver()
defer client.Disconnect(ctx)
a, b := DbInsertOne(client, user)
fmt.Println("Section1", a, b)
}
func ConnectDbWithNewDriver() (client *mongo.Client, ctx context.Context) {
ctx = context.Background()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://127.0.0.1:27017").SetConnectTimeout(5*time.Second))
if err != nil {
fmt.Println("CreateSession: ", err)
client.Disconnect(ctx)
return
}
return
}
func DbInsertOne(client *mongo.Client, data interface{}) (interface{}, error) {
collection := client.Database("swatitest").Collection("users")
insertResult, err := collection.InsertOne(context.TODO(), data)
if err != nil {
return nil, err
}
return insertResult.InsertedID, nil
}
When I run this code then record saved in db like this:
{
"_id" : ObjectId("61af41b32214b16fe93435a6"),
"first_name" : "Swati",
"last_name" : "Sharma",
"full_name" : "Swati Sharma",
"company_name" : "",
"address" : {
"address" : "",
"city" : "",
"state" : "",
"zipcode" : "",
"apt" : "",
"default" : false,
"short_address" : ""
}
}
I want to save like:
{
"_id" : ObjectId("61af41b32214b16fe93435a6"),
"first_name" : "Swati",
"last_name" : "Sharma",
"full_name" : "Swati Sharma",
"company_name" : ""
}
You may use the omitempty bson tag option, all Go drivers handle it and will not save the field if it's value is the zero value (for primitive types).
So add it to all fields you don't want to get saved as empty string:
type AddressStruct struct {
Address string `json:"address" bson:"address,omitempty"`
City string `json:"city" bson:"city,omitempty"`
State string `json:"state" bson:"state,omitempty"`
Zipcode string `json:"zipcode" bson:"zipcode,omitempty"`
Apt string `json:"apt" bson:"apt,omitempty"`
Default bool `json:"default" bson:"default,omitempty"`
Status int8 `json:"status,omitempty" bson:"status,omitempty"`
Country string `json:"country,omitempty" bson:"country,omitempty"`
ShortAddress string `json:"short_address" bson:"short_address,omitempty"`
}
If you can't modify the struct type, then don't save the struct value. Create your own type (where you add omitempty), copy the struct value into it, and save your own copy.
I have created a custom type for a map. I would like to unmarshal an array
json response into the map. The key value of the map changes each time the response is received. The issue I have is the unmarshal function does not map correctly to the custom values.
type id map[string]yp
type yp struct {
f1 string
f2 int
}
func main() {
data := []byte("[{\"unique1\":{\"f1\":\"1\",\"f2\":\"2\"}},{\"unique2\":{\"f1\":\"4\",\"f2\":\"7\"}}]")
var i []id
json.Unmarshal(data,&i)
fmt.Printf("%v",i)
}
Since the source value for f2 is string, you need to add a field tag:
package main
import (
"encoding/json"
"fmt"
)
var data = []byte(`
[
{
"unique1": {"f1": "1", "f2": "2"}
}, {
"unique2": {"f1": "4", "f2": "7"}
}
]
`)
func main() {
var ids []map[string]struct {
F1 string
F2 int `json:"f2,string"`
}
json.Unmarshal(data, &ids)
// [map[unique1:{F1:1 F2:2}] map[unique2:{F1:4 F2:7}]]
fmt.Printf("%+v\n", ids)
}
I wonder what the cause is. This is the code
package main
import (
"context"
"errors"
"fmt"
"time"
"github.com/olivere/elastic"
)
const (
indexName = "applications"
docType = "log"
appName = "myApp"
indexMapping = `{
"mappings" : {
"log" : {
"properties" : {
"app" : { "type" : "keyword" },
"message" : { "type" : "keyowrd" },
"time" : { "type" : "date" }
}
}
}
}`
)
type Log struct {
App string `json:"app"`
Message string `json:"message"`
Time time.Time `json:"time"`
}
func main() {
client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"))
if err != nil {
panic(err)
}
err = createIndexWithLogs(client)
if err != nil {
panic(err)
}
// err = findAndPrintAppLogs(client)
// if err != nil {
// panic(err)
// }
}
I received an error, No Handler for Type Keyword declared on Field ElasticSearch 6.4.3. Based on the information that I got, ES 6.4.3 should use type keyword. I have no idea that my code is not working.
Does anyone know what the mistake is?
Thanks
You have misspelled "keyword" as "keyowrd" for "message" field. Corrected below:
{
"mappings" : {
"log" : {
"properties" : {
"app" : { "type" : "keyword" },
"message" : { "type" : "keyword" },
"time" : { "type" : "date" }
}
}
}
}
I am trying to parse a nested json on GO ,
the json looks like this:
{
"id" : 12345656,
"date" : "2018-05-02-18-16-17",
"lists" : [
{
"empoyee_id": "12343",
"name": "User1"
},
{
"contractor_id" : "12343",
"name": "User1"
},
{
"contractor_id" : "12343",
"name": "User1"
}
]
}
My struct
type Result struct {
id int64 `json:"id"`
Date string `json:"date"`
Lists []string `json:"lists"`
}
I am trying to access it using the following:
var result Result
json.Unmarshal(contents, &result)
How can I change the above to access to the employee_id or the contractor_id fields ?
You need to use another type to store the nested data rather than a slice of strings like so:
package main
import (
"fmt"
"encoding/json"
)
var contents string = `{
"id" : 12345656,
"date" : "2018-05-02-18-16-17",
"lists" : [
{
"empoyee_id": "12343",
"name": "User1"
},
{
"contractor_id" : "12343",
"name": "User1"
},
{
"contractor_id" : "12343",
"name": "User1"
}
]
}`
type Result struct {
ID int64 `json:"id"`
Date string `json:"date"`
Lists []Contractor `json:"lists"`
}
type Contractor struct {
ContractorID string `json:"contractor_id"`
EmployeeID string `json:"employee_id"`
Name string `json:"name"`
}
func main() {
var result Result
err := json.Unmarshal([]byte(contents), &result)
if err != nil {
panic(err)
}
fmt.Println(result)
}
Executable:
https://play.golang.org/p/7dYArgz1V8y
If you just want a single ID field on the nested object then you will need to do a custom unmarshal function on the result to work out which ID is present.