LoginSignup
48
38

More than 5 years have passed since last update.

mgoの基本的な操作まとめ

Last updated at Posted at 2015-06-04

概要

Go言語のMongoDB Driverであるmgoを使ったコレクション、ドキュメントの基本的な操作方法をまとめました。またクエリの書き方についてmongo shellとの対比を行いました。

この記事の内容は下記のバージョンで動作確認を行いました。

mgoの準備

インストール

> go get gopkg.in/mgo.v2

参考サイト

この記事の作成に関して下記のサイトを参考にしました。

mgo GoDoc

MongoDB manual

MongoDB blog

サンプルデータの準備

この記事で説明するサンプルコードの動作確認用に、下記の環境でサンプルデータを作成します。

MongoDBの環境

  • シングルノード
  • データベース: sample
  • コレクション: columbo

コレクションの構造

サンプルデータとして海外テレビドラマの情報を持つコレクションを扱います。コレクションの構造は下記のようになっています。

field data type description
title string 原題
original_air_date string 放送日
runtime integer 放送時間(分)
guest_staring string ゲスト出演
guest_staring_role string ゲスト役柄
directed_by string 監督
written_by array 脚本
teleplay array テレビ脚本
season integer シーズン
no_in_season integer シーズン回
no_in_series integer 放送回
japanese_title String 邦題
japanese_air_date Date 日本放送日

サンプルデータの作成

mongo shellより下記のコマンドを実行してサンプルデータを作成します。
(長いので一部抜粋です、全文は付録Aに記載しています。)

mongo_shell
> db.columbo.drop()
false

> db.columbo.insert([
{title:"Prescription: Murder",                original_air_date:"February 20, 1968",   runtime:98, guest_staring:"Gene Barry",        guest_staring_role:"Dr. Ray Fleming (Gene Barry), a psychiatrist",  directed_by:"Richard Irving",       written_by:["Richard Levinson & William Link"],                  teleplay:[""],                              season:0, no_in_season:1, no_in_series:1,  japanese_title:"殺人処方箋",                     japanese_air_date:ISODate("1972-08-27T00:00:00+09:00")},

省略

{title:"The Conspirators",                    original_air_date:"May 13, 1978",        runtime:98, guest_staring:"Clive Revill",      guest_staring_role:"Famous Irish poet and author Joe Devlin",      directed_by:"Leo Penn",             written_by:["Howard Berk"],                                      teleplay:[""],                              season:7, no_in_season:5, no_in_series:45, japanese_title:"策謀の結末",                      japanese_air_date:ISODate("1979-01-03T00:00:00+09:00"), based_on_an_idea_by: "Pat Robison"}
])
WriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 45,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]

> db.columbo.find().count()
45

サンプルコード

mgoパッケージ

mgoパッケージ、bsonパッケージをインポートします。

go
import (
  "gopkg.in/mgo.v2"
  "gopkg.in/mgo.v2/bson"
)

MongoDBへの接続と切断

MongoDBへ接続するにはDial()DialWithTimeout()DialWithInfo()などを使用します。

Dialを使用して接続します

urlで指定するMongoDBサーバーに接続します。Dial()が成功したときに返すSessionを通してMongoDBの操作を行います。
Sessionは不要になったらリソースを開放するためにClose()を呼ぶ必要があります。閉じたSessionを使用するとエラーが発生します。
Dial()DialWithTimeout()のラッパーメソッドです。タイムアウトは1分で設定されます。

go
session, err := mgo.Dial("localhost:27017")
if err != nil {
  panic(err)
}
defer session.Close()

db := session.DB("sample")

レプリカセットを構成している場合、urlにはそのメンバーをカンマ区切りで指定します。

example
mgo.Dial("localhost:30001,localhost:30002,localhost:30003")

urlのフォーマットは次の通りです。

[mongodb://][user:pass@]host1[:port1][,host2[:port2],...][/database][?options]
DialWithTimeout

タイムアウトする時間を任意の値で設定したい場合はDialWithTimeout()を使用します。timeoutに0を指定すると接続できるまで無期限に待機します。
DialWithTimeout()DialWithInfo()のラッパーメソッドです。

この例では20秒でタイムアウトするように指定しています。

go
session, err := mgo.DialWithTimeout("localhost:27017", 20*time.Second)
if err != nil {
  panic(err)
}
defer session.Close()

db := session.DB("sample")
DialWithInfo

DialWithInfo()DialInfoに設定した情報を使用して接続を行います。ユーザー認証が必要な場合はUsername,Password,Sourceなどに認証情報を設定します。
この例ではsession.DB()に空のデータベース名を指定していますが、DialInfoで指定したデータベース名が使用されます。

go
mongoInfo := &mgo.DialInfo{
  Addrs:    []string{"localhost:27017"},
  Timeout:  20 * time.Second,
  Database: "sample",
  Username: "peter",
  Password: "fark",
  Source: "sample",
}

session, err := mgo.DialWithInfo(mongoInfo)
if err != nil {
  panic(err)
}
defer session.Close()

// Databaseを指定していませんがDialInfoで指定した"sample"にアクセスします
db := session.DB("")

GoDoc

name definition
Dial func Dial(url string) (*Session, error)
DialWithTimeout func DialWithTimeout(url string, timeout time.Duration) (*Session, error)
DialWithInfo func DialWithInfo(info *DialInfo) (*Session, error)
DialInfo type DialInfo struct

Sessionについて

Dial()で取得したSessionをNew(),Copy(),Clone()で複製して、新しいSessionを作成することができます。

New()

オリジナルのセッションと同じパラメータ(一貫性(consistency)、バッチサイズ(batch size)、プリフェッチサイズ(prefetching)、セーフティーモード(safety mode)を含む)で新しいセッションを作成します。
ただし認証情報(Credential)はコピーしません。またオリジナルのセッションとは別に新しいソケットを作成します。

source
func (s *Session) New() *Session {
  s.m.Lock()
  scopy := copySession(s, false)
  s.m.Unlock()
  scopy.Refresh()
  return scopy
}
Copy()

オリジナルのセッションから認証情報(Credential)もコピーする以外はNew()と同じ動作をします。

source
func (s *Session) Copy() *Session {
  s.m.Lock()
  scopy := copySession(s, true)
  s.m.Unlock()
  scopy.Refresh()
  return scopy
}
Clone()

Copy()と同じ動作をしますが、オリジナルのセッションと同じソケットを使用します。

source
func (s *Session) Clone() *Session {
  s.m.Lock()
  scopy := copySession(s, true)
  s.m.Unlock()
  return scopy
}

各メソッドの差異について

method Session parameter Credential Socket
New コピーする クリアする 新しいソケットを使う
Copy コピーする コピーする 新しいソケットを使う
Clone コピーする コピーする オリジナルと同じソケットを使う
認証情報のコピーについて

MongoDBサーバーのドキュメントを操作するのにユーザー認証が必要な場合、session.Login()mgo.DialWithInfo()を使用して認証を行う必要がありますが、この2つには下記の違いがあります。

session.Login()を使用する場合

Dial()時に認証は行わずsession.Login()ではじめて認証を行います。このSessionをNew()で複製しても認証情報はコピーされません。つまり新しいSessionでもsession.Login()で認証を行う必要があります。

go
masterSession, err := mgo.Dial("localhost:27017")
if err != nil {
  panic(err)
}
credential := &mgo.Credential{Username: "peter", Password: "fark", Source: "sample"}
if err := masterSession.Login(credential); err != nil {
  panic(err)
}

newSession := masterSession.New()
cl := newSession.DB("sample").C("columbo")
m := bson.M{}
err = ncl.Find(bson.M{"no_in_series":2}).One(&m)
if err != nil {
  fmt.Printf("Find error:%+v \n", err)
  // ⇒ Find error:not authorized for query on sample.test
} else {
  fmt.Printf("Fine success:%+v \n", m)
}

Copy()はオリジナルのセッションの認証情報もコピーしているのでsession.Login()をしなくても、そのまま使用することができます。

go
copySession := masterSession.Copy()
cl := copySession.DB("sample").C("columbo")
err = cl.Find(bson.M{"no_in_series": 3}).One(&m)
if err != nil {
  fmt.Printf("Find error:%+v \n", err)
} else {
  fmt.Printf("Fine success:%+v \n", m)
  // ⇒ Fine success:map[title:Murder by the Book guest_staring_role:Ken Franklin is one half of a mystery writing team original_air_date:September 15, 1971 japanese_air_date:1972-11-26 00:00:00 +0900 JST _id:ObjectIdHex("557229340aa26682fd8d6408") runtime:73 directed_by:Steven Spielberg teleplay:[] japanese_title:構想の死角 guest_staring:Jack Cassidy written_by:[Steven Bochco] season:1 no_in_season:1 no_in_series:3]
}

mgo.DialWithInfo()を使用する場合

mgo.DailWithInfo()時に認証を行います。このSessionをNew()で複製すると認証情報はコピーされます。つまり新しいSessionですぐにMongoDBのドキュメントを操作することができます。

go
mongoInfo := &mgo.DialInfo{
  Addrs:    []string{"localhost:27017"},
  Timeout:  60 * time.Second,
  Database: "sample",
  Username: "peter",
  Password: "fark",
  Source:   "sample",
}
masterSession, err := mgo.DialWithInfo(mongoInfo)
if err != nil {
  panic(err)
}

cl := masterSession.DB("sample").C("columbo")
err = cl.Find(bson.M{"no_in_series": 1}).One(&m)
if err != nil {
  fmt.Printf("Find error:%+v \n", err)
} else {
  fmt.Printf("Fine success:%+v \n", m)
  // ⇒ Fine success:map[guest_staring_role:Dr. Ray Fleming (Gene Barry), a psychiatrist directed_by:Richard Irving _id:ObjectIdHex("557229340aa26682fd8d6406") runtime:98 season:0 no_in_season:1 no_in_series:1 japanese_air_date:1972-08-27 00:00:00 +0900 JST original_air_date:February 20, 1968 written_by:[Richard Levinson & William Link] japanese_title:殺人処方箋 title:Prescription: Murder teleplay:[] guest_staring:Gene Barry]
}

newSession := masterSession.New()
cl = newSession.DB("sample").C("columbo")
err = ncl.Find(bson.M{"no_in_series": 2}).One(&m)
if err != nil {
  fmt.Printf("Find error:%+v \n", err)
} else {
  fmt.Printf("Fine success:%+v \n", m)
  // ⇒ Fine success:map[title:Ransom for a Dead Man teleplay:[Dean Hargrove] japanese_title:死者の身代金 guest_staring:Lee Grant directed_by:Richard Irving _id:ObjectIdHex("557229340aa26682fd8d6407") runtime:98 guest_staring_role:Leslie Williams, a brilliant lawyer and pilot no_in_season:2 no_in_series:2 japanese_air_date:1973-04-22 00:00:00 +0900 JST original_air_date:March 1, 1971 written_by:[Richard Levinson & William Link] season:0]
}

GoDoc

name definition
Credential type Credential struct

SessionからFind().All()までの関連図(概略)

go
err := session.DB("sample").C("columbo").Find(bson.M{}).All(&result)
         +-[ DialInfo ]-----------------+
         |                              |
 +-------| Addrs          []string      |(Cluster)
 |       | Timeout        time.Duration |
 |       | Database       string        |
 |       | ReplicaSetName string        |(Cluster)
 |       | Source         string        |(Credential)
 |       | Mechanism      string        |(Credential)
 |       | Username       string        |(Credential)
 |       | Password       string        |(Credential)
 |       | PoolLimit      int           |
 |       +------------------------------+
 |       +-[ Credential ]---------------+
 |       |                              |
 |  +----| Username      string         |
 |  |    | Password      string         |
 |  |    | Source        string         |
 |  |    | Service       string         |
 |  |    | ServiceHost   string         |
 |  |    | Mechanism     string         |
 |  |    +------------------------------+
 |  |
 |  |    +-[ Session ]------------------+         +-[ Database ]-----+        +-[ Collection ]-----+
 |  |    |                              |         |                  |        |                    |
Dial()==>| cluster_     *mongoCluster   |==DB()==>| Session *Session |==C()==>| Database *Database |==Find()
         | slaveSocket  *mongoSocket    |         | Name     string  |        | Name      string   |
         | masterSocket *mongoSocket    |         |                  |        | FullName  string   |
         | slaveOk       bool           |         +------------------+        |                    |
         | consistency   mode           |                                     +--------------------+
         | queryConfig   query          |-------------+
         | safeOp       *queryOp        |             |
         | syncTimeout   time.Duration  |             |
         | sockTimeout   time.Duration  |             |
         | defaultdb     string         |             |
         | dialCred     *Credential     |             |
         | creds        []Credential    |         +- [query ]--------+
         | poolLimit     int            |         |                  |
         |                              |         | op       queryOp |
         +------------------------------+         | prefetch float64 |
                                                  | limit    int32   |
                                                  +------------------+

                                                            +-[ Iter ]---------------------+
                                                            |                              |
                                                            | gotReply       sync.Cond     |
                                                            | session        *Session      |
                                                            | server         *mongoServer  |
                                                            | docData        queue         |
                                                            | err            error         |
                                                            | op             getMoreOp     |
                                                            | prefetch       float64       |
                                                            | limit          int32         |
         +-[ Query ]--------------------+                   | docsToReceive  int           |
         |                              |                   | docsBeforeMore int           |
Find()==>| session *Session             |==All()==>Iter()==>| timeout        time.Duration |
         | query                        |                   | timedout       bool          |
         +------------------------------+                   +------------------------------+

GoDoc

name definition
Session type Session struct
Session.DB func (s *Session) DB(name string) *Database
Session.New func (s *Session) New() *Session
Session.Copy func (s *Session) Copy() *Session
Session.Clone func (s *Session) Clone() *Session
Session.Close func (s *Session) Close()

SetMode()

セッションの一貫性モードを変更します。MongoDBがレプリケーション構成の場合に意味を持ちます。

go
session.SetMode(mgo.Monotonic, true)

consistency

value description
mgo.Strong もっとも強い一貫性モードです。データの読み取り、書き込みはプリマリーノードに行います。デフォルトです。
mgo.Monotonic 読み取りはセカンダリーノードで行いますが、書き込みが発生すると以降はプライマリーノードに対して読み取り、書き込みを行います。
mgo.Eventual 結果整合性と呼ばれるモードです。読み取りはセカンダリーノードで行います。書き込みはプライマリーノードに行います。

refresh

refreshにtrueを指定するとセッションのソケットをリリースして新しいソケットを作成します。
consistencyとの組み合わせにより一貫性モードの再設定が行われます。

例) consistencyをmgo.StrongでSessionを作成し、クエリを発行したあとで下記のパターンへ変えた場合。
(masterSocket,slaveSocket欄の0x...はsocketオブジェクトへのポインタがあることを意味します。)

pattern slaveOk masterSocket slaveSocket description
SetMode(mgo.Monotonic, true) true nil 0x... slaveSocketを使用して接続、セカンダリーへ接続可
SetMode(mgo.Monotonic, false) false 0x... nil masterSocketを使用して接続、セカンダリーへ接続不可

例) consistencyをmgo.MonotonicでSessionを作成し、クエリを発行したあとで下記のパターンへ変えた場合。

pattern slaveOk masterSocket slaveSocket description
SetMode(mgo.Strong, true) false 0x... nil masterSocketを使用して接続、セカンダリーへ接続不可
SetMode(mgo.Strong, false) false 0x... 0x... masterSocketを使用して接続、slaveSocketはそのまま、セカンダリーへ接続不可
source
func (s *Session) SetMode(consistency mode, refresh bool) {
  s.m.Lock()
  debugf("Session %p: setting mode %d with refresh=%v (master=%p, slave=%p)", s, consistency, refresh, s.masterSocket, s.slaveSocket)
  s.consistency = consistency
  if refresh {
    s.slaveOk = s.consistency != Strong
    s.unsetSocket()
  } else if s.consistency == Strong {
    s.slaveOk = false
  } else if s.masterSocket == nil {
    s.slaveOk = true
  }
  s.m.Unlock()
}

GoDoc

name definition
Session.SetMode func (s *Session) SetMode(consistency mode, refresh bool)
Session.Mode func (s *Session) Mode() mode
Session.Refresh func (s *Session) Refresh()

SetSafe()

セッションのセーフティーモードを変更します。

Unacknowledged
完全にエラーの検証を無効にします。
更新処理の成否を確認しませんので高速に動作します。

go
session.SetSafe(nil)
go
session.SetSafe(&mgo.Safe{W: 0})

Acknowledged
デフォルトのモードです。
更新処理のエラーの検証を行います。このためgetLastErrorコマンドが実行されます。

go
session.SetSafe(&mgo.Safe{})
go
session.SetSafe(&mgo.Safe{W: 1})

Journaled
データのディスクへの書き込みを確認します。

go
session.SetSafe(&mgo.Safe{W: 1, J: true})

Replica Acknowledged
レプリケーションのメンバーの過半数以上に書き込みされることを保証します。

go
session.SetSafe(&mgo.Safe{WMode: "majority"})

Safe

書き込み保証オプションを下記の通り指定することができます。

option description
safe.W Min # of servers to ack before success
safe.WMode Write mode for MongoDB 2.0+ (e.g. "majority")
safe.WTimeout Milliseconds to wait for W before timing out
safe.FSync Should servers sync to disk before returning success
safe.J Wait for next group commit if journaling; no effect otherwise

GoDoc

name definition
Session.SetSafe func (s *Session) SetSafe(safe *Safe)
Session.Safe func (s *Session) Safe() (safe *Safe)
Safe type Safe struct

SetDebug()

デバッグモードの設定を行います。

Loggerへデバッグログを出力します。
この例では標準出力へデバッグログを出力します。

go
logger := log.New(os.Stdout, "MGO: ", log.Lshortfile)
mgo.SetDebug(true)
mgo.SetLogger(logger)

GoDoc

name definition
SetDebug func SetDebug(debug bool)
SetLogger func SetLogger(logger log_Logger)

データベースの操作

コレクションの取得

コレクションの情報を取得します

mongo_shell
> use sample
switched to db sample

> db.getCollectionNames()
[ "columbo", "system.indexes" ]
go
db := session.DB("sample")

names, _ := db.CollectionNames()
for _, v := range names {
  fmt.Printf("collection name:%s\n", v)
  // ⇒ collection name:columbo
  // ⇒ collection name:system.indexes
}

cl := db.C("columbo")

fmt.Printf("Name:%s, FullName:%s\n", cl.Name, cl.FullName)
// ⇒ Name:columbo, FullName:sample.columbo

GoDoc

name definition
Database type Database struct
Database.C func (db *Database) C(name string) *Collection
Database.CollectionNames func (db *Database) CollectionNames() (names []string, err error)
Collection type Collection struct

キャップド コレクションの作成

この記事で使用するcolumboコレクションは通常のコレクションとして作成しますので特別な操作は不要ですが、キャップドコレクションはcreateCollection()を使用して明示的に作成する必要があります。

mongo_shell
> db.createCollection("columbo",{capped:true, size:1073741824, max:1000000})
{ "ok" : 1 }
go
clInfo := &mgo.CollectionInfo{
  Capped:   true,
  MaxBytes: 1073741824,
  MaxDocs:  1000000,
}
err := cl.Create(clInfo)
if err != nil {
  fmt.Printf("%+v \n", err)
}

GoDoc

name definition
Collection.Create func (c *Collection) Create(info *CollectionInfo) error
CollectionInfo type CollectionInfo struct

ユニークインデックスの作成

例) 放送回(no_in_series)にユニークインデックスを作成します。

mongo_shell
> db.columbo.createIndex({no_in_series:1}, {unique:true, name:"columbo_uni01"})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

mgoではインデックス名を指定することはできないようです。

go
index := mgo.Index{
  Key:    []string{"no_in_series"},
  Unique: true,
}
err := cl.EnsureIndex(index)
if err != nil {
  fmt.Println(err)
}

GoDoc

name definition
Index type Index struct
EnsureIndex func (c *Collection) EnsureIndex(index Index) error

ユーザーの操作

ユーザーの作成と削除

mongo_shell
> db.createUser({user:"peter", pwd:"fark", roles:["readWrite","dbAdmin"]},{w:"majority", wtimeout:3000})
Successfully added user: { "user" : "peter", "roles" : [ "readWrite", "dbAdmin" ] }

> db.auth("peter","fark")
1

> db.logout()
{ "ok" : 1 }

> db.dropUser("peter")
true
go
user := &mgo.User{
  Username: "peter",
  Password: "fark",
  Roles:    []mgo.Role{mgo.RoleReadWrite, mgo.RoleDBAdmin},
}

err = db.UpsertUser(user)
if err != nil {
  fmt.Printf("UpsertUser : %s\n", err)
}

err = db.Login("peter", "fark")
if err != nil {
  fmt.Printf("Login : %s\n", err)
}

db.Logout()

err := db.RemoveUser("peter")
if err != nil {
  fmt.Printf("RemoveUser : %s\n", err)
}

GoDoc

name definition
Database.RemoveUser func (db *Database) RemoveUser(user string) error
Database.UpsertUser func (db *Database) UpsertUser(user *User) error
User type User struct
Role type Role string
Database.Login func (db *Database) Login(user, pass string) error
Database.Logout func (db *Database) Logout()

コレクションの操作

columboコレクションをmgoから扱うための構造体を下記のように定義しました。

go
type Columbo struct {
  ID               bson.ObjectId `bson:"_id,omitempty"`
  Title            string        `bson:"title"`
  OriginalAirDate  string        `bson:"original_air_date,omitempty"`
  Runtime          int           `bson:"runtime,omitempty"`
  GuestStaring     string        `bson:"guest_staring"`
  GuestStaringRole string        `bson:"guest_staring_role"`
  DirectedBy       string        `bson:"directed_by"`
  WrittenBy        []string      `bson:"written_by"`
  Teleplay         []string      `bson:"teleplay,omitempty"`
  Season           int           `bson:"season"`
  NoInSeason       int           `bson:"no_in_season"`
  NoInSeries       int           `bson:"no_in_series"`
  JapaneseTitle    string        `bson:"japanese_title"`
  JapaneseAirDate  time.Time     `bson:"japanese_air_date"`
}

検索 (Find, FindId)

条件を指定して検索します

例) 検索条件にシーズン5のエピソードを指定して検索します。

mongo_shell
> db.columbo.find(
  {season:5},
  {_id:0, title:1, runtime:1, guest_staring:1, season:1, no_in_season:1 no_in_series:1}
)
go
result := []Columbo{}
err := cl.Find(bson.M{"season": 5}).Select(bson.M{"_id": 0, "title": 1, "runtime": 1, "guest_staring": 1, "season": 1, "no_in_season": 1, "no_in_series": 1}).All(&result)
if err != nil {
  fmt.Println(err)
}
for _, v := range result {
  fmt.Printf("%s %d %s %d %d %d\n", v.Title, v.Runtiem, v.GuestStaring, v.Season, v.NoInSeason, v.NoInSeries)
  // ⇒ Forgotten Lady, 85, Janet Leigh, 5, 1, 32
  // ⇒ A Case of Immunity, 73, Héctor Elizondo, 5, 2, 33
  // ⇒ Identity Crisis, 98, Patrick McGoohan, 5, 3, 34
  // ⇒ A Matter of Honor, 73, Ricardo Montalban, 5, 4, 35
  // ⇒ Now You See Him..., 85, Jack Cassidy, 5, 5, 36
  // ⇒ Last Salute to the Commodore, 98, Robert Vaughn, 5, 6, 37
}

All()は検索結果をすべてresultへ格納しようとしますので、検索するドキュメントの件数が多い場合はメモリーを枯渇させる危険性があります。場合によってはAll()Limitを併用する必要があるかもしれません。

GoDoc

name definition
Collection.Find func (c *Collection) Find(query interface{}) *Query
Query.Select func (q *Query) Select(selector interface{}) *Query
Query.All func (q *Query) All(result interface{}) error
Iter.All func (iter *Iter) All(result interface{}) error

検索するドキュメントの件数を制限します

例) 無条件に検索したドキュメントを10件スキップした後の5件を取得します。

mongo_shell
> db.columbo.find().skip(10).limit(5)
go
result := []Columbo{}
err := cl.Find(bson.M{}).Skip(10).Limit(5).All(&result)
if err != nil {
  fmt.Println(err)
}
for _, v := range result {
  fmt.Printf("%s, %d, %s, %d, %d, %d\n", v.Title, v.Runtiem, v.GuestStaring, v.Season, v.NoInSeason, v.NoInSeries)
  // ⇒ The Greenhouse Jungle, 73, Ray Milland, 2, 2, 11
  // ⇒ The Most Crucial Game, 73, Robert Culp, 2, 3, 12
  // ⇒ Dagger of the Mind, 98, Richard Basehart, 2, 4, 13
  // ⇒ Requiem for a Falling Star, 73, Anne Baxter, 2, 5, 14
  // ⇒ A Stitch in Crime, 73, Leonard Nimoy, 2, 6, 15
}

GoDoc

name definition
Query.Limit func (q *Query) Limit(n int) *Query
Query.Skip func (q *Query) Skip(n int) *Query

範囲を指定してドキュメントを検索します

例) 放送回(no_in_series)が30回から39回までのエピソードを検索します。

mongo_shell
> db.columbo.find(
  {$and:[ {no_in_series:{$gte:30}}, {no_in_series:{$lte:39}} ]},
  {_id:0, title:1, runtime:1, guest_staring:1, season:1, no_in_season:1, no_in_series:1}
)
go
result := []Columbo{}
err := cl.Find(bson.M{"$and": []interface{}{
  bson.M{"no_in_series": bson.M{"$gte": 30}},
  bson.M{"no_in_series": bson.M{"$lte": 39}}}}).Select(bson.M{"_id": 0, "title": 1, "runtime": 1, "guest_staring": 1, "season": 1, "no_in_season": 1, "no_in_series": 1}).All(&result)
if err != nil {
  fmt.Println(err)
}
for _, v := range result {
  fmt.Printf("%s, %d, %s, %d, %d, %d\n", v.Title, v.Runtiem, v.GuestStaring, v.Season, v.NoInSeason, v.NoInSeries)
  // ⇒ Playback, 73, Oskar Werner, 4, 5, 30
  // ⇒ A Deadly State of Mind, 73, George Hamilton, 4, 6, 31
  // ⇒ Forgotten Lady, 85, Janet Leigh, 5, 1, 32
  // ⇒ A Case of Immunity, 73, Héctor Elizondo, 5, 2, 33
  // ⇒ Identity Crisis, 98, Patrick McGoohan, 5, 3, 34
  // ⇒ A Matter of Honor, 73, Ricardo Montalban, 5, 4, 35
  // ⇒ Now You See Him..., 85, Jack Cassidy, 5, 5, 36
  // ⇒ Last Salute to the Commodore, 98, Robert Vaughn, 5, 6, 37
  // ⇒ Fade in to Murder, 73, William Shatner, 6, 1, 38
  // ⇒ Old Fashioned Murder, 73, Joyce Van Patten, 6, 2, 39
}

検索したドキュメントをソートします

例) 放送時間(runtime)が98分のエピソードを検索し、放送回(no_in_series)が新しい順に並べ替えます。

mongo_shell
> db.columbo.find(
  {runtime:{$eq:98}},
  {_id:0, title:1, original_air_date:1, runtime:1, guest_staring:1, season:1, no_in_season:1, no_in_series:1}
).sort({no_in_series:-1})
go
result := []Columbo{}
err := cl.Find(bson.M{"runtime": bson.M{"$eq": 98}}).Select(bson.M{"_id": 0, "title": 1, "runtime": 1, "guest_staring": 1, "season": 1, "no_in_season": 1, "no_in_series": 1}).Sort("-no_in_series").All(&result)
if err != nil {
  fmt.Println(err)
}
for _, v := range result {
  fmt.Printf("%s, %d, %s, %d, %d, %d\n", v.Title, v.Runtiem, v.GuestStaring, v.Season, v.NoInSeason, v.NoInSeries)
  // ⇒ The Conspirators, 98, Clive Revill, 7, 5, 45
  // ⇒ Make Me a Perfect Murder, 98, Trish Van Devere, 7, 3, 43
  // ⇒ Last Salute to the Commodore, 98, Robert Vaughn, 5, 6, 37
  // ⇒ Identity Crisis, 98, Patrick McGoohan, 5, 3, 34
  // ⇒ Troubled Waters, 98, Robert Vaughn, 4, 4, 29
  // ⇒ By Dawn's Early Light, 98, Patrick McGoohan, 4, 3, 28
  // ⇒ Negative Reaction, 98, Dick Van Dyke, 4, 2, 27
  // ⇒ An Exercise in Fatality, 98, Robert Conrad, 4, 1, 26
  // ⇒ A Friend in Deed, 98, Richard Kiley, 3, 8, 25
  // ⇒ Swan Song, 98, Johnny Cash, 3, 7, 24
  // ⇒ Candidate for Crime, 98, Jackie Cooper, 3, 3, 20
  // ⇒ Any Old Port in a Storm, 98, Donald Pleasence, 3, 2, 19
  // ⇒ Dagger of the Mind, 98, Richard Basehart, 2, 4, 13
  // ⇒ Étude in Black, 98, John Cassavetes, 2, 1, 10
  // ⇒ Ransom for a Dead Man, 98, Lee Grant, 0, 2, 2
  // ⇒ Prescription: Murder, 98, Gene Barry, 0, 1, 1
}

デフォルトでは昇順、フィールド名の先頭に-を付けると降順にソートします。

GoDoc

name definition
Query.Sort func (q *Query) Sort(fields ...string) *Query

正規表現で検索条件を指定します

例) 放送年に関わらず3月に放送されたエピソードを検索します。

mongo_shell
> db.columbo.find(
  {original_air_date:{$regex:/^March.*/}},
  {_id:0, title:1, original_air_date:1, runtime:1, guest_staring:1, season:1, no_in_season:1, no_in_series:1}
)
go
result := []Columbo{}
err := cl.Find(bson.M{"original_air_date": bson.M{"$regex": bson.RegEx{Pattern: `^March.*`, Options:"m"}}}).Select(bson.M{"_id": 0, "title": 1, "runtime": 1, "guest_staring": 1, "season": 1, "no_in_season": 1, "no_in_series": 1, "original_air_date": 1}).Sort("-no_in_series").All(&result)
if err != nil {
  fmt.Println(err)
}
for _, v := range result {
  fmt.Printf("%s, %d, %s, %d, %d, %d, %s\n", v.Title, v.Runtiem, v.GuestStaring, v.Season, v.NoInSeason, v.NoInSeries, v.OriginalAirDate)
  // ⇒ Ransom for a Dead Man, 98, Lee Grant, 0, 2, 2, March 1, 1971
  // ⇒ The Most Dangerous Match, 73, Laurence Harvey, 2, 7, 16, March 4, 1973
  // ⇒ Double Shock, 73, Martin Landau, 2, 8, 17, March 25, 1973
  // ⇒ Swan Song, 98, Johnny Cash, 3, 7, 24, March 3, 1974
  // ⇒ Playback, 73, Oskar Werner, 4, 5, 30, March 2, 1975
}

Options

option description
i case insensitive matching
m multi-line matching
x verbose mode
l \w, \W, and similar be locale-dependent
s dot-all mode
u \w, \W, and similar match unicode

GoDoc

name definition
RegEx type RegEx struct

条件にあうドキュメントを1件検索します

例) シーズン第1回目のエピソードを1件検索します。

mongo_shell
> db.columbo.findOne(
  {no_in_season:1},
  {_id:0, title:1, original_air_date:1, runtime:1, guest_staring:1, season:1, no_in_season:1, no_in_series:1}
)
go
columbo := &Columbo{}
err := cl.Find(bson.M{"no_in_season": bson.M{"$eq": 1}}).Select(bson.M{"_id": 0, "title": 1, "runtime": 1, "guest_staring": 1, "season": 1, "no_in_season": 1, "no_in_series": 1}).One(&columbo)
if err != nil {
  if v, ok := err.(*mgo.QueryError); ok {
    fmt.Printf("%+v \n", v)
  } else {
    fmt.Printf("%+v \n", err)
  }
}
fmt.Printf("%s, %d, %s, %d, %d, %d\n", columbo.Title, columbo.Runtiem, columbo.GuestStaring, columbo.Season, columbo.NoInSeason, columbo.NoInSeries)
// ⇒ Prescription: Murder, 98, Gene Barry, 0, 1, 1

検索条件にあうドキュメントが見つからなかった場合はErrNotFoundが返ります。
それ以外はerrはQueryError型になります。

例) 下記はSelectメソッドの記述が正しくなかった場合の出力結果になります。

go
if err != nil {
  fmt.Printf("%+v \n", reflect.TypeOf(err))
  // ⇒ *mgo.QueryError
  if v, ok := err.(*mgo.QueryError); ok {
    fmt.Printf("%+v \n", v)
    // ⇒ Can't canonicalize query: BadValue Projection cannot have a mix of inclusion and exclusion.
  } else {
    fmt.Printf("%+v \n", err)
  }
}

GoDoc

name definition
Query.One func (q *Query) One(result interface{}) (err error)
QueryError type QueryError struct

ObjectIdを指定して検索します

mongo_shell
> db.columbo.find(
  {_id:ObjectId("556ce9b2f5c33ee8cd7ea852")},
  {_id:0, title:1, original_air_date:1, runtime:1, guest_staring:1, season:1, no_in_season:1, no_in_series:1}
)
go
columbo := &Columbo{}
err := cl.FindId(bson.ObjectIdHex("556ce9b2f5c33ee8cd7ea852")).One(&columbo)
if err != nil {
  fmt.Println(err)
}
fmt.Printf("%s, %d, %s, %d, %d, %d\n", columbo.Title, columbo.Runtiem, columbo.GuestStaring, columbo.Season, columbo.NoInSeason, columbo.NoInSeries)
// ⇒ Candidate for Crime, 98, Jackie Cooper, 3, 3, 20

FindIdは以下のFindと同じ意味になります。

go
err := cl.Find(bson.M{"_id": bson.ObjectIdHex("556ce9b2f5c33ee8cd7ea852")}).One(&columbo)

検索結果をbson.M型に格納します

特定の型を使用しない方法です。
検索するドキュメントのスキーマが不定の場合などで使用できます。

go
result := bson.M{}
err := cl.Find(bson.M{"no_in_series": 10}).One(&m)
if err != nil {
   fmt.Printf("%+v \n", err)
} else {
  for key, value := range m {
    fmt.Printf("key:%s, value:%v \n", key, value)
    // ⇒ key:guest_staring, value:John Cassavetes
    // ⇒ key:directed_by, value:Nicholas Colasanto
    // ⇒ key:_id, value:ObjectIdHex("5570a16c15cc230577dd7f57")
    // ⇒ key:runtime, value:98
    // ⇒ key:guest_staring_role, value:Alex Benedict, The conductor of the Los Angeles Philharmonic Orchestra
    // ⇒ key:original_air_date, value:September 17, 1972
    // ⇒ key:written_by, value:[Richard Levinson & William Link]
    // ⇒ key:season, value:2
    // ⇒ key:no_in_season, value:1
    // ⇒ key:no_in_series, value:10
    // ⇒ key:japanese_air_date, value:1973-09-30 00:00:00 +0900 JST
    // ⇒ key:teleplay, value:[Steven Bochco]
    // ⇒ key:japanese_title, value:黒のエチュード
    // ⇒ key:title, value:Étude in Black
  }
}

検索結果をbson.D型に格納します

bson.Dでも同様のことが行えます。

go
var d bson.D
err := cl.Find(bson.M{"no_in_series": 10}).One(&d)
if err != nil {
  fmt.Printf("%+v \n", err)
} else {
  for _, elem := range d {
    fmt.Printf("name:%s, value:%v \n", elem.Name, elem.Value)
    // ⇒ name:_id, value:ObjectIdHex("5570a3d815cc230577dd7f8c")
    // ⇒ name:japanese_air_date, value:1973-09-30 00:00:00 +0900 JST
    // ⇒ name:original_air_date, value:September 17, 1972
    // ⇒ name:guest_staring, value:John Cassavetes
    // ⇒ name:written_by, value:[Richard Levinson & William Link]
    // ⇒ name:season, value:2
    // ⇒ name:no_in_season, value:1
    // ⇒ name:no_in_series, value:10
    // ⇒ name:title, value:Étude in Black
    // ⇒ name:runtime, value:98
    // ⇒ name:guest_staring_role, value:Alex Benedict, The conductor of the Los Angeles Philharmonic Orchestra
    // ⇒ name:directed_by, value:Nicholas Colasanto
    // ⇒ name:teleplay, value:[Steven Bochco]
    // ⇒ name:japanese_title, value:黒のエチュード
  }
}

GoDoc

name definition
Collection.FindId func (c *Collection) FindId(id interface{}) *Query
ObjectIdHex func ObjectIdHex(s string) ObjectId

追加 (Insert,Bulk)

1件のドキュメントを追加します

例) シーズン8の第1話を追加します。

mongo_shell
> db.columbo.insert({title:"Columbo Goes to the Guillotine",   runtime:93, guest_staring:"Anthony Andrews", guest_staring_role:"Elliott Blake, A psychic", directed_by:"Leo Penn",      written_by:["William Read Woodfield"], teleplay:[""], season:8, no_in_season:1, no_in_series:46, japanese_title:"汚れた超能力", japanese_air_date:ISODate("1993-05-07T00:00:00+0900")})
WriteResult({ "nInserted" : 1 })
go
lc, _ := time.LoadLocation("Asia/Tokyo")

columbo := Columbo{}
columbo.ID = bson.NewObjectId()
columbo.Title = "Columbo Goes to the Guillotine"
columbo.Runtime = 93
columbo.GuestStaring = "Anthony Andrews"
columbo.GuestStaringRole = "Elliott Blake, A psychic"
columbo.DirectedBy = "Leo Penn"
columbo.WrittenBy = []string{"William Read Woodfield"}
columbo.Teleplay = []string{""}
columbo.Season = 8
columbo.NoInSeason = 1
columbo.NoInSeries = 46
columbo.JapaneseTitle = "汚れた超能力"
columbo.JapaneseAirDate = time.Date(1993, 5, 7, 0, 0, 0, 0, lc)
err := cl.Insert(&columbo)
if err != nil {
  if mgo.IsDup(err) {
    fmt.Printf("Duplicate key error \n")
  }
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
     fmt.Printf("%+v \n", err)
  }
}

errが返ってきた場合mgo.IsDup()で重複エラーか判定することができます。
また、セッションがセーフモードのときのerrはLastError型です。

GoDoc

s v
Collection.Insert func (c *Collection) Insert(docs ...interface{}) error
IsDup func IsDup(err error) bool
LastError type LastError struct

複数件のドキュメントをまとめて追加します

例) シーズン8の残り3話をまとめて追加します。

mongo_shell
> db.columbo.insert([
{title:"Murder, Smoke and Shadows",           runtime:95, guest_staring:"Fisher Stevens",  guest_staring_role:"Boy genius Hollywood director Alex Brady", directed_by:"James Frawley", written_by:["Richard Alan Simmons"],   teleplay:[""], season:8, no_in_season:2, no_in_series:47, japanese_title:"狂ったシナリオ", japanese_air_date:ISODate("1993-06-04T00:00:00+0900")},
{title:"Sex and the Married Detective",       runtime:94, guest_staring:"Lindsay Crouse",  guest_staring_role:"Sex therapist Dr. Joan Allenby", directed_by:"James Frawley", written_by:["Jerry Ludwig"],           teleplay:[""], season:8, no_in_season:3, no_in_series:48, japanese_title:"幻の娼婦", japanese_air_date:ISODate("1993-07-02T00:00:00+09:00")},
{title:"Grand deceptions",                    runtime:95, guest_staring:"Robert Foxworth", guest_staring_role:"Colonel Frank Brailie", directed_by:"Sam Wanamaker", written_by:["Sy Salkowitz"],           teleplay:[""], season:8, no_in_season:4, no_in_series:49, japanese_title:"迷子の兵隊", japanese_air_date:ISODate("1993-09-17T00:00:00+09:00")}
])
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 3,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
go
columboSeason8 := []*Columbo{
&Columbo{ID: bson.NewObjectId(), Title: "Murder, Smoke and Shadows", Runtime: 95, GuestStaring: "Fisher Stevens", GuestStaringRole: "Boy genius Hollywood director Alex Brady", DirectedBy: "James Frawley", WrittenBy: []string{"Richard Alan Simmons"}, Teleplay: []string{""}, Season: 8, NoInSeason: 2, NoInSeries: 47, JapaneseTitle: "狂ったシナリオ", JapaneseAirDate: time.Date(1993, 6, 4, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Sex and the Married Detective", Runtime: 94, GuestStaring: "Lindsay Crouse", GuestStaringRole: "Sex therapist Dr. Joan Allenby", DirectedBy: "James Frawley", WrittenBy: []string{"Jerry Ludwig"}, Teleplay: []string{""}, Season: 8, NoInSeason: 3, NoInSeries: 48, JapaneseTitle: "幻の娼婦", JapaneseAirDate: time.Date(1993, 7, 2, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Grand deceptions", Runtime: 95, GuestStaring: "Robert Foxworth", GuestStaringRole: "Colonel Frank Brailie", DirectedBy: "Sam Wanamaker", WrittenBy: []string{"Sy Salkowitz"}, Teleplay: []string{""}, Season: 8, NoInSeason: 4, NoInSeries: 49, JapaneseTitle: "迷子の兵隊", JapaneseAirDate: time.Date(1993, 9, 17, 0, 0, 0, 0, lc)},
}

ca := make([]interface{}, len(columboSeason8))
for i, v := range columboSeason8 {
  ca[i] = v
}
err = cl.Insert(ca...)
if err != nil {
  fmt.Printf("%+v \n", err)
}

Bulkインサートでドキュメントをまとめて追加します

例) シーズン9の全6話をBulkインサートで追加します。

mongo_shell
> var bulk = db.columbo.initializeOrderedBulkOp()
> bulk.insert({title:"Murder, a Self-Portrait",     original_air_date:"November 25, 1989", guest_staring:"Patrick Bauchau",  guest_staring_role:"Temperamental artist Max Barsini",        directed_by:"James Frawley",    written_by:["Robert Sherman"],         teleplay:[""], no_in_season:1, no_in_series:50, japanese_title:"殺意のキャンバス",     japanese_air_date:ISODate("1994-11-04T00:00:00+09:00")})
> bulk.insert({title:"Columbo Cries Wolf",          original_air_date:"January 20, 1990",  guest_staring:"Ian Buchanan",     guest_staring_role:"men's magazine publisher Sean Brantley",  directed_by:"Daryl Duke",       written_by:["William Read Woodfield"], teleplay:[""], no_in_season:2, no_in_series:51, japanese_title:"だまされたコロンボ",   japanese_air_date:ISODate("1994-06-17T00:00:00+09:00")})
> bulk.insert({title:"Agenda for Murder",           original_air_date:"February 10, 1990", guest_staring:"Patrick McGoohan", guest_staring_role:"Oscar Finch, A lawyer",                   directed_by:"Patrick McGoohan", written_by:["Jeffrey Bloom"],          teleplay:[""], no_in_season:3, no_in_series:52, japanese_title:"完全犯罪の誤算",       japanese_air_date:ISODate("1995-03-17T00:00:00+09:00")})
> bulk.insert({title:"Rest in Peace, Mrs. Columbo", original_air_date:"March 31, 1990",    guest_staring:"Helen Shaver",     guest_staring_role:"Vivian Dimitri, A real-estate executive", directed_by:"Vincent McEveety", written_by:["Peter S. Fischer"],       teleplay:[""], no_in_season:4, no_in_series:53, japanese_title:"かみさんよ、安らかに", japanese_air_date:ISODate("1995-04-14T00:00:00+09:00")})
> bulk.insert({title:"Uneasy Lies the Crown",       original_air_date:"April 28, 1990",    guest_staring:"James Read",       guest_staring_role:"Dentist Dr. Wesley Corman",               directed_by:"Alan J. Levi",     written_by:["Steven Bochco"],          teleplay:[""], no_in_season:5, no_in_series:54, japanese_title:"華麗なる罠",           japanese_air_date:ISODate("1994-12-02T00:00:00+09:00")})
> bulk.insert({title:"Murder in Malib",             original_air_date:"May 14, 1990",      guest_staring:"Andrew Stevens",   guest_staring_role:"Wayne Jennings, Actor",                   directed_by:"Walter Grauman",   written_by:["Jackson Gillis"],         teleplay:[""], no_in_season:6, no_in_series:55, japanese_title:"マリブビーチ殺人事件", japanese_air_date:ISODate("1994-10-14T00:00:00+09:00")})
bulk.execute()
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 6,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
go
columboSeason9 := []*Columbo{
&Columbo{ID: bson.NewObjectId(), Title: "Murder, a Self-Portrait", OriginalAirDate: "November 25, 1989", Runtime: 0, GuestStaring: "Patrick Bauchau", GuestStaringRole: "Temperamental artist Max Barsini", DirectedBy: "James Frawley", WrittenBy: []string{"Robert Sherman"}, Teleplay: []string{""}, NoInSeason: 1, NoInSeries: 50, JapaneseTitle: "殺意のキャンバス", JapaneseAirDate: time.Date(1994, 11, 4, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Columbo Cries Wolf", OriginalAirDate: "January 20, 1990", Runtime: 0, GuestStaring: "Ian Buchanan", GuestStaringRole: "men's magazine publisher Sean Brantley", DirectedBy: "Daryl Duke", WrittenBy: []string{"William Read Woodfield"}, Teleplay: []string{""}, NoInSeason: 2, NoInSeries: 51, JapaneseTitle: "だまされたコロンボ", JapaneseAirDate: time.Date(1994, 6, 17, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Agenda for Murder", OriginalAirDate: "February 10, 1990", Runtime: 0, GuestStaring: "Patrick McGoohan", GuestStaringRole: "Oscar Finch, A lawyer", DirectedBy: "Patrick McGoohan", WrittenBy: []string{"Jeffrey Bloom"}, Teleplay: []string{""}, NoInSeason: 3, NoInSeries: 52, JapaneseTitle: "完全犯罪の誤算", JapaneseAirDate: time.Date(1995, 3, 17, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Rest in Peace, Mrs. Columbo", OriginalAirDate: "March 31, 1990", Runtime: 0, GuestStaring: "Helen Shaver", GuestStaringRole: "Vivian Dimitri, A real-estate executive", DirectedBy: "Vincent McEveety", WrittenBy: []string{"Peter S. Fischer"}, Teleplay: []string{""}, NoInSeason: 4, NoInSeries: 53, JapaneseTitle: "かみさんよ、安らかに", JapaneseAirDate: time.Date(1995, 04, 14, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Uneasy Lies the Crown", OriginalAirDate: "April 28, 1990", Runtime: 0, GuestStaring: "James Read", GuestStaringRole: "Dentist Dr. Wesley Corman", DirectedBy: "Alan J. Levi", WrittenBy: []string{"Steven Bochco"}, Teleplay: []string{""}, NoInSeason: 5, NoInSeries: 54, JapaneseTitle: "華麗なる罠", JapaneseAirDate: time.Date(1994, 12, 2, 0, 0, 0, 0, lc)},
&Columbo{ID: bson.NewObjectId(), Title: "Murder in Malib", OriginalAirDate: "May 14, 1990", Runtime: 0, GuestStaring: "Andrew Stevens", GuestStaringRole: "Wayne Jennings, Actor", DirectedBy: "Walter Grauman", WrittenBy: []string{"Jackson Gillis"}, Teleplay: []string{""}, NoInSeason: 6, NoInSeries: 55, JapaneseTitle: "マリブビーチ殺人事件", JapaneseAirDate: time.Date(1994, 10, 14, 0, 0, 0, 0, lc)},
}

bulk := cl.Bulk()
for _, v := range columboSeason9 {
  bulk.Insert(v)
}

var bulkRes *mgo.BulkResult
var err error
bulkRes, err = bulk.Run()
if err != nil {
  fmt.Printf("%+v \n", err)
}
if bulkRes != nil {
  fmt.Printf("bulkResult: %+v \n", bulkRes)
  // ⇒ bulkResult: &{private:false}
}

bson.M型を使用してドキュメントを追加します

特定の型を使用しない方法です。
マップのキーがそのままMongoDBのドキュメントのフィールド名になります。

go
lc, _ := time.LoadLocation("Asia/Tokyo")

sdocs := []*bson.M{
&bson.M{"title": "Prescription: Murder", "original_air_date": "February 20, 1968", "runtime": 98, "guest_staring": "Gene Barry", "guest_staring_role": "Dr. Ray Fleming (Gene Barry), a psychiatrist", "directed_by": "Richard Irving", "written_by": []string{"Richard Levinson & William Link"}, "teleplay": []string{""}, "season": 0, "no_in_season": 1, "no_in_series": 1, "japanese_title": "殺人処方箋", "japanese_air_date": time.Date(1972, 8, 27, 0, 0, 0, 0, lc)},
&bson.M{"title": "Ransom for a Dead Man", "original_air_date": "March 1, 1971", "runtime": 98, "guest_staring": "Lee Grant", "guest_staring_role": "Leslie Williams, a brilliant lawyer and pilot", "directed_by": "Richard Irving", "written_by": []string{"Richard Levinson & William Link"}, "teleplay": []string{"Dean Hargrove"}, "season": 0, "no_in_season": 2, "no_in_series": 2, "japanese_title": "死者の身代金", "japanese_air_date": time.Date(1973, 4, 22, 0, 0, 0, 0, lc)},
&bson.M{"title": "Murder by the Book", "original_air_date": "September 15, 1971", "runtime": 73, "guest_staring": "Jack Cassidy", "guest_staring_role": "Ken Franklin is one half of a mystery writing team", "directed_by": "Steven Spielberg", "written_by": []string{"Steven Bochco"}, "teleplay": []string{""}, "season": 1, "no_in_season": 1, "no_in_series": 3, "japanese_title": "構想の死角", "japanese_air_date": time.Date(1972, 11, 26, 0, 0, 0, 0, lc)},
}
docs := make([]interface{}, len(sdocs))
for i, v := range sdocs {
  docs[i] = v
}
err := cl.Insert(docs...)
if err != nil {
  log.Prinf("%+v \n", err)
}

GoDoc

name definition
Bulk type Bulk struct
Bulk.Insert func (b *Bulk) Insert(docs ...interface{})
Bulk.Run func (b *Bulk) Run() (*BulkResult, error)
BulkResult type BulkResult struct

更新 (Update, UpdateId)

条件にあうドキュメントを1件更新します

例) 指定するエピソードの放送日(original_air_date)を更新します。

mongo_shell
> db.columbo.update({title:"Columbo Goes to the Guillotine"},{$set:{original_air_date:"February 6, 1989"}})

selectorの条件に一致するドキュメントが複数ある場合でも更新されるのはそのうちの1件だけです。

go
selector := bson.M{"title": "Columbo Goes to the Guillotine"}
update := bson.M{"$set": bson.M{"original_air_date": "February 6, 1989"}}
err := cl.Update(selector, update)
if err != nil {
  if mgo.IsDup(err) {
    fmt.Printf("Duplicate key error \n")
  }
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
}

範囲を指定して複数件を更新します

例) 放送回(no_in_series)が50回から55回までをシーズン9として更新します。

mongo_shell
> db.columbo.update({$and:[{no_in_series:{$gte:50}},{no_in_series:{$lte:55}}]},{$set:{season:9}},{multi:true})
WriteResult({ "nMatched" : 6, "nUpserted" : 0, "nModified" : 6 })
go
selector := bson.M{"$and": []interface{}{
  bson.M{"no_in_series": bson.M{"$gte": 50}},
  bson.M{"no_in_series": bson.M{"$lte": 55}}},
}
update := bson.M{"$set": bson.M{"season": 9}}
changeInfo, err := cl.UpdateAll(selector, update)
if err != nil {
  if mgo.IsDup(err) {
    fmt.Printf("Duplicate key error \n")
  }
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
}
if changeInfo != nil {
  fmt.Printf("%+v \n", changeInfo)
  // ⇒ &{Updated:6 Removed:0 UpsertedId:<nil>}
}

ObjectIdを指定して更新します

例) ObjectIdで指定するドキュメントの放送日(original_air_date)を更新します。

mongo_shell
> db.columbo.update({_id:ObjectId("556f1a1fafaf9f0864000012")},{$set:{original_air_date:"February 27, 1989"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
go
id := bson.ObjectIdHex("556ce9b2f5c33ee8cd7ea852")
update := bson.M{"$set": bson.M{"original_air_date": "February 27, 1989"}}
err := cl.UpdateId(id, update)
if err != nil {
  if mgo.IsDup(err) {
    fmt.Printf("Duplicate key error \n")
  }
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
}

GoDOc

name definition
Collection.Update func (c *Collection) Update(selector interface{}, update interface{}) error
Collection.UpdateAll func (c *Collection) UpdateAll(selector interface{}, update interface{}) (info *ChangeInfo, err error)
Collection.UpdateId func (c *Collection) UpdateId(id interface{}, update interface{}) error
ErrNotFound var ErrNotFound = errors.New("not found")

追加 or 更新 (Upsert, UpsertId)

追加・更新を行います

事前に対象になるドキュメントを削除しておきます。
コレクションに無いドキュメントをupsertモードで追加し、その後そのドキュメントのフィールドを更新します。

mongo_shell
> db.columbo.remove({season:8})

> db.columbo.update(
  {title:"Columbo Goes to the Guillotine"},
  {title:"Columbo Goes to the Guillotine",  runtime:93, guest_staring:"Anthony Andrews", guest_staring_role:"Elliott Blake, A psychic",                 directed_by:"Leo Penn",      written_by:["William Read Woodfield"], teleplay:[""], season:8, no_in_season:1, no_in_series:46, japanese_title:"汚れた超能力", japanese_air_date:ISODate("1993-05-07T00:00:00+0900")},
  {upsert:true}
)
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("557090f515cc230577dd7eac")
})

> db.columbo.update(
  {title: "Columbo Goes to the Guillotine"},
  {$set:{original_air_date:"February 27, 1989"}},
  {upsert:true}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
go
// season 8 all delete
ci, err := cl.RemoveAll(bson.M{"season": 8})
if err != nil {
  fmt.Printf("%+v \n", err)
}

// コレクションに存在しないドキュメントをupsertで追加します
lc, _ := time.LoadLocation("Asia/Tokyo")
selector := bson.M{"title": "Columbo Goes to the Guillotine"}
columbo := Columbo{ID: bson.NewObjectId(), Title: "Columbo Goes to the Guillotine", Runtime: 93, GuestStaring: "Anthony Andrews", GuestStaringRole: "Elliott Blake, A psychic", DirectedBy: "Leo Penn", WrittenBy: []string{"William Read Woodfield"}, Teleplay: []string{""}, Season: 8, NoInSeason: 1, NoInSeries: 46, JapaneseTitle: "汚れた超能力", JapaneseAirDate: time.Date(1993, 5, 7, 0, 0, 0, 0, lc)}
ci, err = cl.Upsert(selector, &columbo)
if err != nil {
  fmt.Printf("%+v \n", err)
}
if ci != nil {
  fmt.Printf("%+v \n", ci)
  // ⇒ &{Updated:0 Removed:0 UpsertedId:ObjectIdHex("55709323afaf9f019000001b")}
}

// upsertでフィールドを更新します
update := bson.M{"$set": bson.M{"original_air_date": "February 27, 1989"}}
ci, err = cl.Upsert(selector, update)
if err != nil {
  fmt.Printf("%+v \n", err)
}
if ci != nil {
  fmt.Printf("%+v \n", ci)
  // ⇒ &{Updated:1 Removed:0 UpsertedId:<nil>}
}

GoDoc

name definition
Collection.Upsert func (c *Collection) Upsert(selector interface{}, update interface{}) (info *ChangeInfo, err error)
Collection.UpsertId func (c *Collection) UpsertId(id interface{}, update interface{}) (info *ChangeInfo, err error)

削除 (Remove, RemoveId)

条件を指定して1件削除します

例) シーズン8のエピソードを1件削除します。(どのエピソードかは不定です。)

mongo_shell
> db.columbo.remove({season:8}, {justOne:true})
WriteResult({ "nRemoved" : 0 })
go
selector := bson.M{"season": 8}
err := cl.Remove(selector)
if err != nil {
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
}

セッションがセーフモードの場合、条件にあうドキュメントが見つからなかった場合はErrNotFoundが返ります。
それ以外のエラーのときerrはLastError型になります。

条件にあうドキュメントを全て削除します

例) シーズン8のエピソードをすべて削除します。

mongo_shell
> db.columbo.remove({season:8})
go
selector := bson.M{"season": 8}
changeInfo, err := cl.RemoveAll(selector)
if err != nil {
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
if changeInfo != nil {
  fmt.Printf("Removed:%d, Updated:%d \n", changeInfo.Removed, changeInfo.Updated)
}

セッションがセーフモードのときのerrはLastError型です。

無条件に全件削除します

例) コレクションのドキュメントをすべて削除します。

mongo_shell
> db.columbo.remove({})
WriteResult({ "nRemoved" : 55 })
go
changeInfo, err := cl.RemoveAll(nil)
if err != nil {
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("%+v \n", err)
  }
}
if changeInfo != nil {
  fmt.Printf("Removed:%d, Updated:%d \n", changeInfo.Removed, changeInfo.Updated)
  // ⇒ Removed:55, Updated:0
}

ObjectIdを指定して削除します

mongo_shell
> db.columbo.remove({_id:ObjectId("556f1a1fafaf9f0864000012")})
WriteResult({ "nRemoved" : 1 })
go
id := bson.ObjectIdHex("556ce9b2f5c33ee8cd7ea852")
err := cl.RemoveId(id)
if err != nil {
  if v, ok := err.(*mgo.LastError); ok {
    fmt.Printf("Code:%d N:%d UpdatedExisting:%t WTimeout:%t Waited:%d \n", v.Code, v.N, v.UpdatedExisting, v.WTimeout, v.Waited)
  } else {
    fmt.Printf("RemoveId: %+v \n", err)
  }
}

RemoveIdは下記のRemoveと同じ意味になります。

go
id := bson.ObjectIdHex("556ce9b2f5c33ee8cd7ea852")
err := cl.Remove(bson.M{"_id": id})

GoDoc

name definition
Collection.Remove func (c *Collection) Remove(selector interface{}) error
Collection.RemoveId func (c *Collection) RemoveId(id interface{}) error
Collection.RemoveAll func (c *Collection) RemoveAll(selector interface{}) (info *ChangeInfo, err error)
ErrNotFound

付録

A. サンプルデータ作成スクリプト

シーズン0からシーズン7までのデータを作成します。

mongo_shell
> db.columbo.drop()
false

> db.columbo.insert([
{title:"Prescription: Murder",                original_air_date:"February 20, 1968",   runtime:98, guest_staring:"Gene Barry",        guest_staring_role:"Dr. Ray Fleming (Gene Barry), a psychiatrist",  directed_by:"Richard Irving",       written_by:["Richard Levinson & William Link"],                  teleplay:[""],                              season:0, no_in_season:1, no_in_series:1,  japanese_title:"殺人処方箋",                     japanese_air_date:ISODate("1972-08-27T00:00:00+09:00")},
{title:"Ransom for a Dead Man",               original_air_date:"March 1, 1971",       runtime:98, guest_staring:"Lee Grant",         guest_staring_role:"Leslie Williams, a brilliant lawyer and pilot", directed_by:"Richard Irving",       written_by:["Richard Levinson & William Link"],                  teleplay:["Dean Hargrove"],                 season:0, no_in_season:2, no_in_series:2,  japanese_title:"死者の身代金",                   japanese_air_date:ISODate("1973-04-22T00:00:00+09:00")},
{title:"Murder by the Book",                  original_air_date:"September 15, 1971",  runtime:73, guest_staring:"Jack Cassidy",      guest_staring_role:"Ken Franklin is one half of a mystery writing team", directed_by:"Steven Spielberg",     written_by:["Steven Bochco"],                                    teleplay:[""],                              season:1, no_in_season:1, no_in_series:3,  japanese_title:"構想の死角",                japanese_air_date:ISODate("1972-11-26T00:00:00+09:00")},
{title:"Death Lends a Hand",                  original_air_date:"October 6, 1971",     runtime:73, guest_staring:"Robert Culp",       guest_staring_role:"Carl Brimmer, The head of a private detective agency",directed_by:"Bernard L. Kowalski",  written_by:["RRichard Levinson & William Link"],                 teleplay:[""],                              season:1, no_in_season:2, no_in_series:4,  japanese_title:"指輪の爪あと",             japanese_air_date:ISODate("1973-01-21T00:00:00+09:00")},
{title:"Dead Weight",                         original_air_date:"October 27, 1971",    runtime:73, guest_staring:"Eddie Albert",      guest_staring_role:"Major General Martin Hollister, a retired Marine Corps war hero",               directed_by:"Jack Smight",          written_by:["John T. Dugan"],                                    teleplay:[""],                              season:1, no_in_season:3, no_in_series:5,  japanese_title:"ホリスター将軍のコレクション", japanese_air_date:ISODate("1972-09-24T00:00:00+09:00")},
{title:"Suitable for Framing",                original_air_date:"November 17, 1971",   runtime:73, guest_staring:"Ross Martin",       guest_staring_role:"Dale Kingston, Art critic",                     directed_by:"Hy Averback",          written_by:["Jackson Gillis"],                                   teleplay:[""],                              season:1, no_in_season:4, no_in_series:6,  japanese_title:"二枚のドガの絵",                 japanese_air_date:ISODate("1972-10-22T00:00:00+09:00")},
{title:"Lady in Waiting",                     original_air_date:"December 15, 1971",   runtime:73, guest_staring:"Susan Clark",       guest_staring_role:"Beth Chadwick, sister of domineering, Bryce",   directed_by:"Norman Lloyd",         written_by:["Barney Slater"],                                    teleplay:["Steven Bochco"],                 season:1, no_in_season:5, no_in_series:7,  japanese_title:"もう一つの鍵",                   japanese_air_date:ISODate("1972-12-17T00:00:00+09:00")},
{title:"Short Fuse",                          original_air_date:"January 19, 1972",    runtime:73, guest_staring:"Roddy McDowall",    guest_staring_role:"Roger Stanford, A chemist",                     directed_by:"Edward M. Abrams",     written_by:["Lester & Tina Pine","Jackson Gillis"],              teleplay:["Jackson Gillis"],                season:1, no_in_season:6, no_in_series:8,  japanese_title:"死の方程式",                     japanese_air_date:ISODate("1973-03-18T00:00:00+09:00")},
{title:"Blueprint for Murder",                original_air_date:"February 9, 1972",    runtime:73, guest_staring:"Patrick O'Neal",    guest_staring_role:"Elliot Markham, An architect",                  directed_by:"Peter Falk",           written_by:["William Kelley"],                                   teleplay:["Steven Bochco"],                 season:1, no_in_season:7, no_in_series:9,  japanese_title:"パイルD-3の壁",                  japanese_air_date:ISODate("1973-02-25T00:00:00+09:00")},
{title:"Étude in Black",                      original_air_date:"September 17, 1972",  runtime:98, guest_staring:"John Cassavetes",   guest_staring_role:"Alex Benedict, The conductor of the Los Angeles Philharmonic Orchestra",  directed_by:"Nicholas Colasanto",   written_by:["Richard Levinson & William Link"],      teleplay:["Steven Bochco"],                 season:2, no_in_season:1, no_in_series:10, japanese_title:"黒のエチュード",   japanese_air_date:ISODate("1973-09-30T00:00:00+09:00")},
{title:"The Greenhouse Jungle",               original_air_date:"October 15, 1972",    runtime:73, guest_staring:"Ray Milland",       guest_staring_role:"Jarvis Goodland, An expert in orchids",         directed_by:"Boris Sagal",          written_by:["Jonathan Latimer"],                                 teleplay:[""],                              season:2, no_in_season:2, no_in_series:11, japanese_title:"悪の温室",                       japanese_air_date:ISODate("1973-05-27T00:00:00+09:00")},
{title:"The Most Crucial Game",               original_air_date:"November 5, 1972",    runtime:73, guest_staring:"Robert Culp",       guest_staring_role:"Paul Hanlon, The general manager of the Los Angeles Rockets football team",  directed_by:"Jeremy Kagan",         written_by:["John T. Dugan"],                   teleplay:[""],                              season:2, no_in_season:3, no_in_series:12, japanese_title:"アリバイのダイヤル", japanese_air_date:ISODate("1973-06-24T00:00:00+09:00")},
{title:"Dagger of the Mind",                  original_air_date:"November 26, 1972",   runtime:98, guest_staring:"Richard Basehart",  guest_staring_role:"Actors Nicholas Framer and his wife, Lillian Stanhope", directed_by:"Richard Quine",        written_by:["Richard Levinson & William Link"],                  teleplay:["Jackson Gillis"],                season:2, no_in_season:4, no_in_series:13, japanese_title:"ロンドンの傘",           japanese_air_date:ISODate("1973-07-29T00:00:00+09:00")},
{title:"Requiem for a Falling Star",          original_air_date:"January 21, 1973",    runtime:73, guest_staring:"Anne Baxter",       guest_staring_role:"movie star Nora Chandler",                     directed_by:"Richard Quine",        written_by:["Jackson Gillis"],                          teleplay:[""],                              season:2, no_in_season:5, no_in_series:14, japanese_title:"偶像のレクイエム",                         japanese_air_date:ISODate("1973-08-26T00:00:00+09:00")},
{title:"A Stitch in Crime",                   original_air_date:"February 11, 1973",   runtime:73, guest_staring:"Leonard Nimoy",     guest_staring_role:"Cardiac surgeon Dr. Barry Mayfield",           directed_by:"Hy Averback",          written_by:["Shirl Hendryx"],                                    teleplay:[""],                              season:2, no_in_season:6, no_in_series:15, japanese_title:"溶ける糸",                        japanese_air_date:ISODate("1973-10-28T00:00:00+09:00")},
{title:"The Most Dangerous Match",            original_air_date:"March 4, 1973",       runtime:73, guest_staring:"Laurence Harvey",   guest_staring_role:"Chess Grandmaster Emmett Clayton",             directed_by:"Edward M. Abroms",     written_by:["Jackson Gillis","Richard Levinson & William Link"], teleplay:["Jackson Gillis"],                season:2, no_in_season:7, no_in_series:16, japanese_title:"断たれた音",                      japanese_air_date:ISODate("1973-11-25T00:00:00+09:00")},
{title:"Double Shock",                        original_air_date:"March 25, 1973",      runtime:73, guest_staring:"Martin Landau",     guest_staring_role:"Flamboyant television chef Dexter Paris and his twin brother, conservative banker Norman",  directed_by:"Robert Butler",        written_by:["Jackson Gillis","Richard Levinson & William Link"], teleplay:["Steven Bochco"],  season:2, no_in_season:8, no_in_series:17, japanese_title:"二つの顔", japanese_air_date:ISODate("1973-12-23T00:00:00+09:00")},
{title:"Lovely But Lethal",                   original_air_date:"September 23, 1973",  runtime:73, guest_staring:"Vera Miles",        guest_staring_role:"Cosmetics queen Viveca Scott",                 directed_by:"Jeannot Szwarc",       written_by:["Myrna Bercovici"],                                  teleplay:["Jackson Gillis"],                season:3, no_in_season:1, no_in_series:18, japanese_title:"毒のある花",                      japanese_air_date:ISODate("1974-09-14T00:00:00+09:00")},
{title:"Any Old Port in a Storm",             original_air_date:"October 7, 1973",     runtime:98, guest_staring:"Donald Pleasence",  guest_staring_role:"Wine connoisseur Adrian Carsini",              directed_by:"Leo Penn",             written_by:["Larry Cohen"],                                      teleplay:["Stanley Ralph Ross"],            season:3, no_in_season:2, no_in_series:19, japanese_title:"別れのワイン",                    japanese_air_date:ISODate("1974-06-29T00:00:00+09:00")},
{title:"Candidate for Crime",                 original_air_date:"November 4, 1973",    runtime:98, guest_staring:"Jackie Cooper",     guest_staring_role:"Nelson Hayward, is coercing the womanizing senatorial candidate",  directed_by:"Boris Sagal",          written_by:["Larry Cohen"],                                      teleplay:["Irving Pearlberg & Alvin R. Friedman","Roland Kibbee & Dean Hargrove"], season:3, no_in_season:3, no_in_series:20, japanese_title:"野望の果て", japanese_air_date:ISODate("1974-08-17T00:00:00+09:00")},
{title:"Double Exposure",                     original_air_date:"December 16, 1973",   runtime:73, guest_staring:"Robert Culp",       guest_staring_role:"Dr. Bart Keppel, A motivation research specialist",  directed_by:"Richard Quine",        written_by:["Stephen J. Cannell"],                               teleplay:[""],                              season:3, no_in_season:4, no_in_series:21, japanese_title:"意識の下の映像",            japanese_air_date:ISODate("1974-08-10T00:00:00+09:00")},
{title:"Publish or Perish",                   original_air_date:"January 18, 1974",    runtime:73, guest_staring:"Jack Cassidy",      guest_staring_role:"Riley Greenleaf, Publisher",                   directed_by:"Robert Butler",        written_by:["Peter S. Fischer"],                                 teleplay:[""],                              season:3, no_in_season:5, no_in_series:22, japanese_title:"第三の終章",                      japanese_air_date:ISODate("1974-12-14T00:00:00+09:00")},
{title:"Mind Over Mayhem",                    original_air_date:"February 10, 1974",   runtime:73, guest_staring:"José Ferrer",       guest_staring_role:"Dr. Marshall Cahill, director of a high-tech Pentagon think tank",  directed_by:"Alf Kjellin",          written_by:["Robert Specht"],                                    teleplay:["Steven Bochco","Dean Hargrove & Roland Kibbee"], season:3, no_in_season:6, no_in_series:23, japanese_title:"愛情の計算", japanese_air_date:ISODate("1974-08-31T00:00:00+09:00")},
{title:"Swan Song",                           original_air_date:"March 3, 1974",       runtime:98, guest_staring:"Johnny Cash",       guest_staring_role:"Gospel-singing superstar Tommy Brown",         directed_by:"Nicholas Colasanto",   written_by:["Stanley Ralph Ross"],                               teleplay:["David Rayfiel"],                 season:3, no_in_season:7, no_in_series:24, japanese_title:"白鳥の歌",                        japanese_air_date:ISODate("1974-09-21T00:00:00+09:00")},
{title:"A Friend in Deed",                    original_air_date:"May 5, 1974",         runtime:98, guest_staring:"Richard Kiley",     guest_staring_role:"Deputy police commissioner Mark Halperin",     directed_by:"Ben Gazzara",          written_by:["Peter S. Fischer"],                                 teleplay:[""],                              season:3, no_in_season:8, no_in_series:25, japanese_title:"権力の墓穴",                      japanese_air_date:ISODate("1974-10-05T00:00:00+09:00")},
{title:"An Exercise in Fatality",             original_air_date:"September 15, 1974",  runtime:98, guest_staring:"Robert Conrad",     guest_staring_role:"Renowned exercise guru Milo Janus",            directed_by:"Bernard L. Kowalski",  written_by:["Larry Cohen"],                                      teleplay:["Peter S. Fischer"],              season:4, no_in_season:1, no_in_series:26, japanese_title:"自縛の紐",                        japanese_air_date:ISODate("1975-12-27T00:00:00+09:00")},
{title:"Negative Reaction",                   original_air_date:"October 6, 1974",     runtime:98, guest_staring:"Dick Van Dyke",     guest_staring_role:"professional photographer Paul Galesko",       directed_by:"Alf Kjellin",          written_by:["Peter S. Fischer"],                                 teleplay:[""],                              season:4, no_in_season:2, no_in_series:27, japanese_title:"逆転の構図",                      japanese_air_date:ISODate("1975-12-20T00:00:00+09:00")},
{title:"By Dawn's Early Light",               original_air_date:"October 27, 1974",    runtime:98, guest_staring:"Patrick McGoohan",  guest_staring_role:"Colonel Lyle C. Rumford, head of the Haynes Military Academy",    directed_by:"Harvey Hart",          written_by:["Howard Berk"],                                      teleplay:[""],                              season:4, no_in_season:3, no_in_series:28, japanese_title:"祝砲の挽歌",   japanese_air_date:ISODate("1976-01-10T00:00:00+09:00")},
{title:"Troubled Waters",                     original_air_date:"February 9, 1975",    runtime:98, guest_staring:"Robert Vaughn",     guest_staring_role:"Auto executive Hayden Danziger",               directed_by:"Ben Gazzara",          written_by:["Jackson Gillis","William Driskill"],                teleplay:["William Driskill"],              season:4, no_in_season:4, no_in_series:29, japanese_title:"歌声の消えた海",                  japanese_air_date:ISODate("1976-01-03T00:00:00+09:00")},
{title:"Playback",                            original_air_date:"March 2, 1975",       runtime:73, guest_staring:"Oskar Werner",      guest_staring_role:"Harold Van Wick, the gadget-obsessed president of Midas Electronics",  directed_by:"Bernard L. Kowalski",  written_by:["David P. Lewis & Booker T. Bradshaw"],       teleplay:[""],                              season:4, no_in_season:5, no_in_series:30, japanese_title:"ビデオテープの証言", japanese_air_date:ISODate("1976-12-11T00:00:00+09:00")},
{title:"A Deadly State of Mind",              original_air_date:"April 27, 1975",      runtime:73, guest_staring:"George Hamilton",   guest_staring_role:"Psychiatrist Dr. Mark Collier",                directed_by:"Harvey Hart",          written_by:["Peter S. Fischer"],                                 teleplay:[""],                              season:4, no_in_season:6, no_in_series:31, japanese_title:"5時30分の目撃者",                 japanese_air_date:ISODate("1976-12-18T00:00:00+09:00")},
{title:"Forgotten Lady",                      original_air_date:"September 14, 1975",  runtime:85, guest_staring:"Janet Leigh",       guest_staring_role:"Aging former movie star Grace Wheeler",  directed_by:"Harvey Hart",          written_by:["Bill Driskill"],                                          teleplay:[""],                              season:5, no_in_season:1, no_in_series:32, japanese_title:"忘れられたスター",                japanese_air_date:ISODate("1977-01-03T00:00:00+09:00")},
{title:"A Case of Immunity",                  original_air_date:"October 12, 1975",    runtime:73, guest_staring:"Héctor Elizondo",   guest_staring_role:"Hassan Salah, chief diplomat of the Legation of Swahari",    directed_by:"Ted Post",             written_by:["James Menzies"],                                    teleplay:["Lou Shaw"],                      season:5, no_in_season:2, no_in_series:33, japanese_title:"ハッサン・サラーの反逆", japanese_air_date:ISODate("1976-12-25T00:00:00+09:00")},
{title:"Identity Crisis",                     original_air_date:"November 2, 1975",    runtime:98, guest_staring:"Patrick McGoohan",  guest_staring_role:"speech-writing consultant Nelson Brenner",     directed_by:"Patrick McGoohan",     written_by:["Bill Driskill"],                                    teleplay:[""],                              season:5, no_in_season:3, no_in_series:34, japanese_title:"仮面の男",                        japanese_air_date:ISODate("1977-09-24T00:00:00+09:00")},
{title:"A Matter of Honor",                   original_air_date:"February 1, 1976",    runtime:73, guest_staring:"Ricardo Montalban", guest_staring_role:"Luis Montoya, A Mexican national hero",        directed_by:"Ted Post",             written_by:["Brad Radnitz"],                                     teleplay:[""],                              season:5, no_in_season:4, no_in_series:35, japanese_title:"闘牛士の栄光",                    japanese_air_date:ISODate("1977-10-01T00:00:00+09:00")},
{title:"Now You See Him...",                  original_air_date:"February 29, 1976",   runtime:85, guest_staring:"Jack Cassidy",      guest_staring_role:"Great Santini, a magician extraordinaire",     directed_by:"Harvey Hart",          written_by:["Michael Sloan"],                                    teleplay:[""],                              season:5, no_in_season:5, no_in_series:36, japanese_title:"魔術師の幻想",                    japanese_air_date:ISODate("1977-12-31T00:00:00+09:00")},
{title:"Last Salute to the Commodore",        original_air_date:"May 2, 1976",         runtime:98, guest_staring:"Robert Vaughn",     guest_staring_role:"Son-in-law Charles Clay",                      directed_by:"Patrick McGoohan",     written_by:["Jackson Gillis"],                                   teleplay:[""],                              season:5, no_in_season:6, no_in_series:37, japanese_title:"さらば提督",                      japanese_air_date:ISODate("1977-10-08T00:00:00+09:00")},
{title:"Fade in to Murder",                   original_air_date:"October 10, 1976",    runtime:73, guest_staring:"William Shatner",   guest_staring_role:"Egocentric actor Ward Fowler",                 directed_by:"Bernard L. Kowalski",  written_by:["Henry Garson"],                                     teleplay:["Lou Shaw","Peter S. Feibleman"], season:6, no_in_season:1, no_in_series:38, japanese_title:"ルーサン警部の犯罪",              japanese_air_date:ISODate("1977-12-17T00:00:00+09:00")},
{title:"Old Fashioned Murder",                original_air_date:"November 28, 1976",   runtime:73, guest_staring:"Joyce Van Patten",  guest_staring_role:"Ruth Lytton, Owner of the Lytton Museum",      directed_by:"Robert Douglas",       written_by:["Lawrence Vail"],                                    teleplay:["Peter S. Feibleman"],            season:6, no_in_season:2, no_in_series:39, japanese_title:"黄金のバックル",                  japanese_air_date:ISODate("1977-12-24T00:00:00+09:00")},
{title:"The Bye-Bye Sky High IQ Murder Case", original_air_date:"May 22, 1977",        runtime:73, guest_staring:"Theodore Bikel",    guest_staring_role:"Oliver Brandt, a senior partner in an accounting firm",  directed_by:"Sam Wanamaker",        written_by:["Robert Malcolm Young"],                   teleplay:[""],                              season:6, no_in_season:3, no_in_series:40, japanese_title:"殺しの序曲",                      japanese_air_date:ISODate("1978-05-20T00:00:00+09:00")},
{title:"Try and Catch Me",                    original_air_date:"November 21, 1977",   runtime:73, guest_staring:"Ruth Gordon",       guest_staring_role:"Mystery author Abigail Mitchell",              directed_by:"James Frawley",        written_by:["Gene Thompson"],                                    teleplay:["Gene Thompson & Paul Tuckahoe"], season:7, no_in_season:1, no_in_series:41, japanese_title:"死者のメッセージ",                japanese_air_date:ISODate("1978-04-08T00:00:00+09:00")},
{title:"Murder Under Glass",                  original_air_date:"January 30, 1978",    runtime:73, guest_staring:"Louis Jourdan",     guest_staring_role:"Renowned restaurant critic Paul Gerard",       directed_by:"Jonathan Demme",       written_by:["Robert van Scoyk"],                                 teleplay:[""],                              season:7, no_in_season:2, no_in_series:42, japanese_title:"美食の報酬",                      japanese_air_date:ISODate("1978-05-27T00:00:00+09:00")},
{title:"Make Me a Perfect Murder",            original_air_date:"February 28, 1978",   runtime:98, guest_staring:"Trish Van Devere",  guest_staring_role:"TV programmer Kay Freestone",                  directed_by:"James Frawley",        written_by:["Robert Blees"],                                     teleplay:[""],                              season:7, no_in_season:3, no_in_series:43, japanese_title:"秒読みの殺人",                    japanese_air_date:ISODate("1979-01-02T00:00:00+09:00")},
{title:"How to Dial a Murder",                original_air_date:"April 15, 1978",      runtime:73, guest_staring:"Nicol Williamson",  guest_staring_role:"Mind control seminar guru Dr. Eric Mason",     directed_by:"James Frawley",        written_by:["Anthony Lawrence"],                                 teleplay:["Tom Lazarus"],                   season:7, no_in_season:4, no_in_series:44, japanese_title:"攻撃命令",                        japanese_air_date:ISODate("1979-01-04T00:00:00+09:00")},
{title:"The Conspirators",                    original_air_date:"May 13, 1978",        runtime:98, guest_staring:"Clive Revill",      guest_staring_role:"Famous Irish poet and author Joe Devlin",      directed_by:"Leo Penn",             written_by:["Howard Berk"],                                      teleplay:[""],                              season:7, no_in_season:5, no_in_series:45, japanese_title:"策謀の結末",                      japanese_air_date:ISODate("1979-01-03T00:00:00+09:00"), based_on_an_idea_by: "Pat Robison"}
])
WriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 45,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]

> db.columbo.find().count()
45
48
38
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
38