使用Go语言从MongoDB读取文档

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

Reading documents from MongoDB with GoLang

问题

我能够读写数据库中的文档,但我遇到了一些非常奇怪的行为。

如果搜索名字为"jack",我会得到所有的文档,而如果搜索名字为"Mike",我只会得到一个文档,但实际上有两个。

搜索方法:

  1. func findByFirstName(name string) {
  2. fmt.Println("looking for - ", name)
  3. client, ctx, _ := getConnection()
  4. quickstart := client.Database("ginPlay")
  5. namesCollection := quickstart.Collection("names")
  6. var p []person
  7. nameObject, err := namesCollection.Find(ctx, bson.M{"lastName": bson.D{
  8. {"$gt", name},
  9. }})
  10. if err = nameObject.All(ctx, &p); err != nil {
  11. panic(err)
  12. }
  13. for i := 0; i < len(p); i++ {
  14. fmt.Println(p[i])
  15. }
  16. }

输出结果:

  1. looking for - Jack
  2. Connected to MongoDB!
  3. {ObjectID("613b706bf47bc212c3928870") Mike Smith 25 Netflix}
  4. {ObjectID("613b706cf47bc212c3928872") Jack Jill 36 Surfing}
  5. {ObjectID("613b706ef47bc212c3928874") Jack Jill 25 Hiking}
  6. {ObjectID("613b706ff47bc212c3928876") Jack Jill 30 Snowboarding}
  7. looking for - Mike
  8. Connected to MongoDB!
  9. {ObjectID("613b706bf47bc212c3928870") Mike Smith 25 Netflix}

数据库中的内容如下:

  1. r.GET("/addPerson", func(c *gin.Context) {
  2. c.String(http.StatusOK, "Hello World!")
  3. p1 := person{Name: "Mike", LastName: "Foo", Age: 36, Hobbies: "Development"}
  4. p2 := person{Name: "Mike", LastName: "Smith", Age: 25, Hobbies: "Netflix"}
  5. p3 := person{Name: "Jack", LastName: "Jill", Age: 36, Hobbies: "Surfing"}
  6. p4 := person{Name: "Jack", LastName: "Jill", Age: 25, Hobbies: "Hiking"}
  7. p5 := person{Name: "Jack", LastName: "Jill", Age: 30, Hobbies: "Snowboarding"}
  8. writePerson(p1)
  9. writePerson(p2)
  10. writePerson(p3)
  11. writePerson(p4)
  12. writePerson(p5)
  13. })

数据库连接:

  1. // GetConnection - 获取到 DocumentDB 的客户端
  2. func getConnection() (*mongo.Client, context.Context, context.CancelFunc) {
  3. username := "foo"
  4. password := "pass"
  5. clusterEndpoint := "cluster0.ml6z7m.mongodb.net/db?retryWrites=true&w=majority"
  6. connectionURI := fmt.Sprintf(connectionStringTemplate, username, password, clusterEndpoint)
  7. client, err := mongo.NewClient(options.Client().ApplyURI(connectionURI))
  8. if err != nil {
  9. log.Printf("Failed to create client: %v", err)
  10. }
  11. ctx, cancel := context.WithTimeout(context.Background(), connectTimeout*time.Second)
  12. err = client.Connect(ctx)
  13. if err != nil {
  14. log.Printf("Failed to connect to cluster: %v", err)
  15. }
  16. // 强制连接以验证连接字符串
  17. err = client.Ping(ctx, nil)
  18. if err != nil {
  19. log.Printf("Failed to ping cluster: %v", err)
  20. }
  21. fmt.Println("Connected to MongoDB!")
  22. return client, ctx, cancel
  23. }

控制器:

  1. r.GET("/mike", func(c *gin.Context) {
  2. c.String(http.StatusOK, "Mike")
  3. findByFirstName("Mike")
  4. })
  5. r.GET("/jack", func(c *gin.Context) {
  6. c.String(http.StatusOK, "Jack")
  7. findByFirstName("Jack")
  8. })

person 结构体:

  1. type person struct {
  2. ID primitive.ObjectID `bson:"_id,omitempty"`
  3. Name string `bson:"name,omitempty"`
  4. LastName string `bson:"lastName,omitempty"`
  5. Age int `bson:"age,omitempty"`
  6. Hobbies string `bson:"hobbies,omitempty"`
  7. }
英文:

I am able to read and write documents to database but I am experiencing some very strange behavior.

If search for the name "jack" I get every document and Mike I get just one document but they're two.

search method

  1. func findByFirstName(name string) {
  2. fmt.Println(&quot;looking for - &quot;, name)
  3. client, ctx, _ := getConnection()
  4. quickstart := client.Database(&quot;ginPlay&quot;)
  5. namesCollection := quickstart.Collection(&quot;names&quot;)
  6. var p []person
  7. nameObject, err := namesCollection.Find(ctx, bson.M {&quot;lastName&quot;: bson.D {
  8. {&quot;$gt&quot;, name},
  9. }})
  10. if err = nameObject.All(ctx, &amp;p); err != nil {
  11. panic(err)
  12. }
  13. for i := 0; i &lt; len(p); i++ {
  14. fmt.Println(p[i])
  15. }
  16. }

output

  1. looking for - Jack
  2. Connected to MongoDB!
  3. {ObjectID(&quot;613b706bf47bc212c3928870&quot;) Mike Smith 25 Netflix}
  4. {ObjectID(&quot;613b706cf47bc212c3928872&quot;) Jack Jill 36 Surfing}
  5. {ObjectID(&quot;613b706ef47bc212c3928874&quot;) Jack Jill 25 Hiking}
  6. {ObjectID(&quot;613b706ff47bc212c3928876&quot;) Jack Jill 30 Snowboarding}
  7. looking for - Mike
  8. Connected to MongoDB!
  9. {ObjectID(&quot;613b706bf47bc212c3928870&quot;) Mike Smith 25 Netflix}

this is what is in the database

  1. r.GET(&quot;/addPerson&quot;, func(c *gin.Context) {
  2. c.String(http.StatusOK, &quot;Hello World!&quot;)
  3. p1 := person{Name: &quot;Mike&quot;, LastName: &quot;Foo&quot;, Age: 36, Hobbies: &quot;Development&quot;}
  4. p2 := person{Name: &quot;Mike&quot;, LastName: &quot;Smith&quot;, Age: 25, Hobbies: &quot;Netflix&quot;}
  5. p3 := person{Name: &quot;Jack&quot;, LastName: &quot;Jill&quot;, Age: 36, Hobbies: &quot;Surfing&quot;}
  6. p4 := person{Name: &quot;Jack&quot;, LastName: &quot;Jill&quot;, Age: 25, Hobbies: &quot;Hiking&quot;}
  7. p5 := person{Name: &quot;Jack&quot;, LastName: &quot;Jill&quot;, Age: 30, Hobbies: &quot;Snowboarding&quot;}
  8. writePerson(p1)
  9. writePerson(p2)
  10. writePerson(p3)
  11. writePerson(p4)
  12. writePerson(p5)
  13. })

database connection

  1. // GetConnection - Retrieves a client to the DocumentDB
  2. func getConnection() (*mongo.Client, context.Context, context.CancelFunc) {
  3. username := &quot;foo&quot;
  4. password := &quot;pass&quot;
  5. clusterEndpoint := &quot;cluster0.ml6z7m.mongodb.net/db?retryWrites=true&amp;w=majority&quot;
  6. connectionURI := fmt.Sprintf(connectionStringTemplate, username, password, clusterEndpoint)
  7. client, err := mongo.NewClient(options.Client().ApplyURI(connectionURI))
  8. if err != nil {
  9. log.Printf(&quot;Failed to create client: %v&quot;, err)
  10. }
  11. ctx, cancel := context.WithTimeout(context.Background(), connectTimeout * time.Second)
  12. err = client.Connect(ctx)
  13. if err != nil {
  14. log.Printf(&quot;Failed to connect to cluster: %v&quot;, err)
  15. }
  16. // Force a connection to verify our connection string
  17. err = client.Ping(ctx, nil)
  18. if err != nil {
  19. log.Printf(&quot;Failed to ping cluster: %v&quot;, err)
  20. }
  21. fmt.Println(&quot;Connected to MongoDB!&quot;)
  22. return client, ctx, cancel

}

controller

  1. r.GET(&quot;/mike&quot;, func(c *gin.Context) {
  2. c.String(http.StatusOK, &quot;Mike&quot;)
  3. findByFirstName(&quot;Mike&quot;)
  4. })
  5. r.GET(&quot;/jack&quot;, func(c *gin.Context) {
  6. c.String(http.StatusOK, &quot;Jack&quot;)
  7. findByFirstName(&quot;Jack&quot;)
  8. })
  9. type person struct {
  10. ID primitive.ObjectID `bson:&quot;_id,omitempty&quot;`
  11. Name string `bson:&quot;name,omitempty&quot;`
  12. LastName string `bson:&quot;lastName,omitempty&quot;`
  13. Age int `bson:&quot;age,omitempty&quot;`
  14. Hobbies string `bson:&quot;hobbies,omitempty&quot;`
  15. }

答案1

得分: 1

findByFirstName()函数在给定的代码中通过lastName进行搜索,并对该字段执行大于($gt)操作,与给定的name进行比较:

  1. nameObject, err := namesCollection.Find(ctx, bson.M {"lastName": bson.D {
  2. {"$gt", name},
  3. }})

你可能犯了一个错误,想要将"lastName"更改为"name"

只有Mike Smith被找到,因为Smith大于Mike(Mongo进行二进制字符串比较-参见这里)。同样的原因,即使对于Jack,输出也不正确;它还包括Mike Smith,因为SmithJill都大于Jack,但不大于Foo

英文:

Function findByFirstName() is searching by lastName and performs greater-than ($gt) operation on that field and given name in posted code:

  1. nameObject, err := namesCollection.Find(ctx, bson.M {&quot;lastName&quot;: bson.D {
  2. {&quot;$gt&quot;, name},
  3. }})

You probably made a mistake and want to change &quot;lastName&quot; to &quot;name&quot;.

Only Mike Smith is found because Smith > Mike (Mongo does binary string comparison - see here). Also, even for Jack output is not correct for the very same reason; it includes also Mike Smith as both Smith and Jill are > than Jack but not Foo.

huangapple
  • 本文由 发表于 2021年9月10日 22:59:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/69134199.html
匿名

发表评论

匿名网友

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

确定