Convert data from mongo to struct

xuanbao · · 562 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi all,</p> <p>I am working on a small side project to learn go and I have hit an issue that hours of Googling and trying have made no impact on for me.</p> <p>I am storing records in mongodb via <code>mgo</code>, which works fine. I can pull records from mongo and send JSON perfectly.</p> <p>However when I try to convert the data from mongo back into concrete types I am &#34;missing&#34; data that implements the &#34;Alert&#34; interface.</p> <pre><code>package main import ( &#34;encoding/json&#34; &#34;fmt&#34; &#34;log&#34; &#34;net/http&#34; &#34;github.com/aws/aws-sdk-go/aws&#34; &#34;github.com/aws/aws-sdk-go/aws/credentials&#34; &#34;github.com/aws/aws-sdk-go/aws/session&#34; &#34;github.com/aws/aws-sdk-go/service/sns&#34; mgo &#34;gopkg.in/mgo.v2&#34; &#34;gopkg.in/mgo.v2/bson&#34; ) type Alert interface { Send(message string) error } type EndPoint struct { Name string `json:&#34;name&#34; bson:&#34;name&#34;` URI string `json:&#34;uri&#34; bson:&#34;uri&#34;` Method string `json:&#34;method&#34; bson:&#34;method&#34;` IgnoreSSL bool `json:&#34;ignoreSsl&#34; bson:&#34;ignoreSsl&#34;` CheckInterval string `json:&#34;checkInterval&#34; bson:&#34;checkInterval&#34;` LastStatus bool `json:&#34;lastStatus&#34; bson:&#34;lastStatus&#34;` Headers http.Header `json:&#34;headers&#34; bson:&#34;headers&#34;` Alerts []Alert `json:&#34;alerts&#34; bson:&#34;alerts&#34;` } type ConsoleAlert struct { Type string `json:&#34;type&#34; bson:&#34;type&#34;` } func (ca ConsoleAlert) Send(message string) error { log.Println(message) return nil } type SNSAlert struct { Type string `json:&#34;type&#34; bson:&#34;type&#34;` Region string `json:&#34;region&#34; bson:&#34;region&#34;` Key string `json:&#34;key&#34; bson:&#34;key&#34;` Secret string `json:&#34;secret&#34; bson:&#34;secret&#34;` TopicARN string `json:&#34;topic_arn&#34; bson:&#34;topic_arn&#34;` } func getSession(sa SNSAlert) (*session.Session, error) { sess, err := session.NewSession(&amp;aws.Config{ Region: aws.String(sa.Region), Credentials: credentials.NewStaticCredentials(sa.Key, sa.Secret, &#34;&#34;), }) if err != nil { return &amp;session.Session{}, err } return sess, nil } func (sa SNSAlert) Send(message string) error { sess, err := getSession(sa) if err != nil { return err } svc := sns.New(sess) params := &amp;sns.PublishInput{ Message: aws.String(message), TopicArn: aws.String(sa.TopicARN), } _, err = svc.Publish(params) if err != nil { return err } return nil } func main() { session, err := mgo.Dial(&#34;localhost&#34;) if err != nil { panic(err) } defer session.Close() DB := session.DB(&#34;mogon&#34;) COL := DB.C(&#34;serverstest&#34;) var bsonEPs []bson.M err = COL.Find(bson.M{}).All(&amp;bsonEPs) if err != nil { fmt.Println(err) } jsonResp, merr := json.Marshal(bsonEPs) if merr != nil { fmt.Println(err) } // We can get the data just fine as JSON fmt.Printf(&#34;\nJSON DATA\n&#34;) fmt.Println(string(jsonResp)) var endpoints []interface{} json.Unmarshal(jsonResp, &amp;endpoints) fmt.Printf(&#34;\nSTRUCT DATA\n&#34;) fmt.Println(endpoints) // mgo can&#39;t Find into a slice of EndPoints var bsonEPsAttempt = make([]EndPoint, 10) err = COL.Find(bson.M{}).All(&amp;bsonEPsAttempt) if err != nil { fmt.Println(err) } fmt.Println(bsonEPsAttempt) } </code></pre> <p>Below is the console output when trying to get EndPoints</p> <pre><code>JSON DATA [{&#34;_id&#34;:&#34;5a0e42ab26d6291543f2128b&#34;,&#34;alerts&#34;:[{&#34;type&#34;:&#34;console&#34;},{&#34;key&#34;:&#34;AWS KEY&#34;,&#34;region&#34;:&#34;us-east-1&#34;,&#34;secret&#34;:&#34;AWS SECRET&#34;,&#34;topic_arn&#34;:&#34;arn:aws:sns:us-east-1:424242:alert&#34;,&#34;type&#34;:&#34;sns&#34;}],&#34;checkInterval&#34;:&#34;14s&#34;,&#34;headers&#34;:{&#34;authKey&#34;:[&#34;password&#34;]},&#34;ignoreSsl&#34;:false,&#34;lastStatus&#34;:false,&#34;method&#34;:&#34;GET&#34;,&#34;name&#34;:&#34;myserver&#34;,&#34;uri&#34;:&#34;https://myapp.com/check&#34;}] STRUCT DATA [map[alerts:[map[type:console] map[key:AWS KEY region:us-east-1 secret:AWS SECRET topic_arn:arn:aws:sns:us-east-1:424242:alert type:sns]] headers:map[authKey:[password]] lastStatus:false method:GET uri:https://myapp.com/check _id:5a0e42ab26d6291543f2128b checkInterval:14s ignoreSsl:false name:myserver]] []EndPoint FAIL reflect.Set: value of type bson.M is not assignable to type alerts.Alert [] </code></pre> <p>How can I reliably create an EndPoint?</p> <hr/>**评论:**<br/><br/>Kraigius: <pre><p>Umm..you didn&#39;t post the struct for alerts.Alert and can you post a minimal repro case?</p></pre>xandout: <pre><p>I have edited the code above, <code>alerts.Alert</code> is now <code>Alert</code></p></pre>Kraigius: <pre><p>Thanks. I admit that I didn&#39;t try your code but I have a better understanding of it now. I found one thread on stackoverflow that seems to suggest that it&#39;s not possible without a workaround but I&#39;ll keep looking.</p> <p><a href="https://stackoverflow.com/questions/26039580/how-to-use-interface-type-as-a-model-in-mgo-go" rel="nofollow">https://stackoverflow.com/questions/26039580/how-to-use-interface-type-as-a-model-in-mgo-go</a></p> <p><strong>edit</strong>: <a href="https://stackoverflow.com/questions/23581884/unable-to-assert-type-string-from-interface" rel="nofollow">related?</a></p></pre>xandout: <pre><p>Ended up with a less than elegant solution involving a switch and json marshalling.</p> <p>Thanks for the tips</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

562 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传