使用Go检索MongoDB文档时出现问题

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

Issues retrieving MongoDB documents with Go

问题

我有以下的代码,但我不确定为什么它没有返回一个Notes的切片。我正在使用来自labix.org的mgo库连接到MongoDB,并遵循他们的在线文档。

  1. type Note struct {
  2. Url string
  3. Title string
  4. Date string
  5. Body string
  6. }
  7. func loadNotes() ([]Note) {
  8. session, err := mgo.Dial("localhost")
  9. if err != nil {
  10. panic(err)
  11. }
  12. defer session.Close()
  13. // 可选。将会话切换到单调行为。
  14. session.SetMode(mgo.Monotonic, true)
  15. c := session.DB("test").C("notes")
  16. notes := []Note{}
  17. iter := c.Find(nil).Limit(100).Iter()
  18. err = iter.All(&notes)
  19. if err != nil {
  20. panic(iter.Err())
  21. }
  22. return notes
  23. }
  24. func main() {
  25. notes := loadNotes()
  26. for note := range notes {
  27. fmt.Println(note.Title)
  28. }
  29. }

如果我只打印出notes,我得到的是看起来像是两个结构体的切片,但我无法通过notes.Title或其他方式访问它们。

  1. [{ Some example title 20 September 2012 Some example content}]

这是我的文档的样子:

  1. > db.notes.find()
  2. { "_id" : "some-example-title", "title" : "Some example title", "date" : "20 September 2012", "body" : "Some example content" }

真正的问题是它将notes作为一个大的切片返回,而不是一个Note{}(我想是这样的?)

如果我做了明显错误的事情,请提供任何见解。

英文:

I have the following code, and I'm not sure why it is not returning a slice of Notes. I am using the mgo library from labix.org to connect to MongoDB and following their online documentation.

  1. type Note struct {
  2. Url string
  3. Title string
  4. Date string
  5. Body string
  6. }
  7. func loadNotes() ([]Note) {
  8. session, err := mgo.Dial("localhost")
  9. if err != nil {
  10. panic(err)
  11. }
  12. defer session.Close()
  13. // Optional. Switch the session to a monotonic behavior.
  14. session.SetMode(mgo.Monotonic, true)
  15. c := session.DB("test").C("notes")
  16. notes := []Note{}
  17. iter := c.Find(nil).Limit(100).Iter()
  18. err = iter.All(&notes)
  19. if err != nil {
  20. panic(iter.Err())
  21. }
  22. return notes
  23. }
  24. func main() {
  25. notes := loadNotes()
  26. for note := range notes {
  27. fmt.Println(note.Title)
  28. }
  29. }

If I just print out notes I get what looks like a slice of two structs, but I can't access them by means of notes.Title or anything like that.

  1. [{ Some example title 20 September 2012 Some example content}]

This is what my documents look like:

  1. > db.notes.find()
  2. { "_id" : "some-example-title", "title" : "Some example title", "date" : "20 September 2012", "body" : "Some example content" }

The real issue is that it's returning the notes as one big slice rather than a Note{} (I think?)

If I'm doing something obviously wrong, any insight would help.

答案1

得分: 5

你的问题在这里:

  1. for note := range notes {
  2. fmt.Println(note.Title)
  3. }

应该改为:

  1. for _, note := range notes {
  2. fmt.Println(note.Title)
  3. }

在切片上使用range语句会返回形式为i, v的一对值,其中i是切片中的索引,v是该索引处的项。由于你省略了第二个值,所以你在循环中使用的是索引,而不是Note值。

这在规范的RangeClause部分有说明:http://golang.org/ref/spec#RangeClause

英文:

your problem is here:

  1. for note := range notes {
  2. fmt.Println(note.Title)
  3. }

it should read:

  1. for _, note := range notes {
  2. fmt.Println(note.Title)
  3. }

using a range statement on a slice returns pairs of the form i, v, where i is the index in the slice, and v is the item at the index in that slice. Since you omitted the second value, you're looping on indexes, not on Note values.

It's in the RangeClause section of the spec: http://golang.org/ref/spec#RangeClause

答案2

得分: 2

看起来对我来说它正在工作。notes是一个你指示的结构体切片。

  1. for _, n := range notes {
  2. n.Title // 对标题进行操作
  3. n.Url // 对URL进行操作
  4. }

或者,如果你只想要第一个:

notes[0].Title 也可以工作。

结构体切片不能像结构体本身那样进行索引,因为它不是一个结构体。

英文:

It looks like it's working to me. notes is a slice of structs as you indicated.

  1. for _, n := range notes {
  2. n.Title // do something with title
  3. n.Url // do something with url
  4. }

or alternatively if you just want the first one:
notes[0].Title should work as well.

A slice of structs can't be indexed as if it were a struct itself because it isn't a struct.

答案3

得分: 0

iter.All()一次性将整个结果集检索到一个切片中。如果你只想要一行数据,使用iter.Next()。请参阅https://groups.google.com/forum/#!msg/mgo-users/yUGZi70ik9Y/J8ktshJgF7QJ

英文:

iter.All() retrieves the whole result set at once into a slice. If you just want one row, use iter.Next(). See https://groups.google.com/forum/#!msg/mgo-users/yUGZi70ik9Y/J8ktshJgF7QJ

huangapple
  • 本文由 发表于 2012年9月24日 12:09:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/12558741.html
匿名

发表评论

匿名网友

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

确定