Help us understand the problem. What is going on with this article?

goのmgoでfindするときの処理

More than 3 years have passed since last update.

はじめに

go言語でmongoDBにアクセスするためのライブラリにmgoがあります。mgoでデータベースからfindしてくるときの処理について、書きたいと思います。

サンプル

サンプルとして以下のようなコードで2件データを挿入しておきます。

package main

import (
    "log"

    mgo "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

type Man struct {
    Id   bson.ObjectId `bson:"_id"`
    Name string        `bson:"name"`
}

func main() {
    session, err := mgo.Dial("mongodb://localhost/")
    if err != nil {
        log.Fatal(err)
    }
    defer session.Close()
    c := session.DB("some-db-name").C("man")

    if err := c.Insert(Man{
        Id:   bson.NewObjectId(),
        Name: "Taro",
    }, Man{
        Id:   bson.NewObjectId(),
        Name: "Jiro",
    }); err != nil {
        log.Fatal(err)
    }

}

全件取得

Findメソッドにnilあるいはbson.M{}を渡すと全件取得できます。

    var men []Man
    if err := c.Find(nil).All(&men); err != nil {
        log.Fatal(err)
    }

    spew.Dump(men)
    /*
        ([]main.Man) (len=2 cap=2) {
         (main.Man) {
          Id: (bson.ObjectId) (len=12) ObjectIdHex("565edd868bc93d268a13bc01"),
          Name: (string) (len=4) "Taro"
         },
         (main.Man) {
          Id: (bson.ObjectId) (len=12) ObjectIdHex("565edd868bc93d268a13bc02"),
          Name: (string) (len=4) "Jiro"
         }
        }
    */

絞り込み

上述のFindメソッドに条件を指定できます。
以下のサイトに記載されているmongoのオペレータは同様に使えます。
https://docs.mongodb.org/manual/reference/operator/query/

    //例 name が Taro か Hanako
    var men []Man
    if err := c.Find(bson.M{
        "name": bson.M{
            "$in": []string{"Taro", "Hanako"},
        },
    }).All(&men); err != nil {
        log.Fatal(err)
    }

ObjectIdで1件取得

"565edd868bc93d268a13bc02" というようなId形式の文字列でfindするときは、ObjectId型に変換しなければいけません。
bson.ObjectIdHex(string)で変換するのですが、ObjectIdの形式の文字列ではない場合、panicします(panic: Invalid input to ObjectIdHex:)。
そのため、bson.IsObjectIdHex(string)でチェックしてから変換するのが安全です。

    idStr := "565edd868bc93d268a13bc02"
    if !bson.IsObjectIdHex(idStr) {
        log.Fatal("not objectId")
    }
    id := bson.ObjectIdHex(idStr)

    var man Man
    if err := c.FindId(id).One(&man); err != nil {
        log.Fatal(err)
    }
    spew.Dump(man)
    /*
        (main.Man) {
         Id: (bson.ObjectId) (len=12) ObjectIdHex("565edd868bc93d268a13bc02"),
         Name: (string) (len=4) "Jiro"
        }
    */

注意として、FindIdでマッチするデータが存在しない場合、エラーとして返されます。
そのため、存在しない場合を別途処理するときは、以下のように記述する必要があります。

    if err := c.FindId(id).One(&man); err != nil {
        if err == mgo.ErrNotFound {
            fmt.Println("Not found")
        } else {
            log.Fatal(err)
        }
    }

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away