Overview
このガイドでは、読み取り操作を使用して MongoDB コレクションからデータを検索する方法を学びます。
読み取り操作では、次の操作を実行できます。
サンプル データ
このガイドの例では、 tea
コレクション内のドキュメントのモデルとして、次の Tea
構造体を使用します。
type Tea struct { Item string `bson:"item,omitempty"` Rating int32 `bson:"rating,omitempty"` DateOrdered time.Time `bson:"date_ordered,omitempty"` }
このガイドの例を実行するには、次のスニペットを使用して、これらのドキュメントをdb
データベースのtea
コレクションにロードします。
coll := client.Database("db").Collection("tea") docs := []interface{}{ Tea{Item: "Masala", Rating: 10, DateOrdered: time.Date(2009, 11, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 7, DateOrdered: time.Date(2009, 11, 18, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 9, DateOrdered: time.Date(2009, 11, 12, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 8, DateOrdered: time.Date(2009, 12, 1, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 10, DateOrdered: time.Date(2009, 12, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Hibiscus", Rating: 4, DateOrdered: time.Date(2009, 12, 18, 0, 0, 0, 0, time.Local)}, } result, err := coll.InsertMany(context.TODO(), docs)
Tip
存在しないデータベースとコレクション
書き込み操作を実行するときに必要なデータベースとコレクションが存在しない場合は、サーバーが暗黙的にそれらを作成します。
各ドキュメントには、カスタマーが注文したお茶の品種、評価、注文日が記載されています。 これらの説明は、 item
、 rating
、 date_ordered
フィールドに対応します。
検索操作
検索操作を使用して、MongoDB からデータを取得します。 Find()
検索操作は、FindOne()
メソッドと メソッドで構成されています。
複数ドキュメントの検索
Find()
メソッドでは、 Context
型とクエリフィルターを渡す必要があります。 メソッドでは、フィルターに一致するすべてのドキュメントがCursor
タイプとして返されます。
次の例では、コンテキスト、フィルター、 FindOptions
をFind()
メソッドに渡し、次のアクションを実行します。
rating
の値が5
から9
まで(排他的)のドキュメントに一致します一致したドキュメントを の昇順でソートします
date_ordered
filter := bson.D{ {"$and", bson.A{ bson.D{{"rating", bson.D{{"$gt", 5}}}}, bson.D{{"rating", bson.D{{"$lt", 9}}}}, }}, } sort := bson.D{{"date_ordered", 1}} opts := options.Find().SetSort(sort) // Retrieves documents that match the filter and prints them as structs cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []Tea if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"item":"Sencha","rating":7,"date_ordered":"2009-11-18T05:00:00Z"} {"item":"Masala","rating":8,"date_ordered":"2009-12-01T05:00:00Z"}
カーソルを使用してデータにアクセスする方法については、「 カーソルからのデータへのアクセスガイド 」を参照してください。
「ドキュメントを検索する例:完全なファイル」
注意
セットアップ例
この例では、接続 URI を使用してMongoDBのインスタンスに接続します。MongoDBインスタンスへの接続の詳細については、MongoClient の作成 ガイドを参照してください。この例では、Atlasサンプルデータセットに含まれる sample_restaurants
データベースの restaurants
コレクションも使用します。「Atlas を使い始める」ガイドに従って、 MongoDB Atlasの無料階層のデータベースにロードできます。
次の例では、restaurants
コレクション内で cuisine
の値が "Italian"
であるすべてのドキュメントを検索します。この例では、一致したドキュメントを参照し、ドキュメントをスライスに解凍するカーソルが返されます。
// Retrieves documents that match a query filter by using the Go driver package main import ( "context" "encoding/json" "fmt" "log" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) // Creates a Restaurant struct as a model for documents in the restaurants collection type Restaurant struct { ID bson.ObjectID `bson:"_id"` Name string RestaurantId string `bson:"restaurant_id"` Cuisine string Address interface{} Borough string Grades interface{} } func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") } var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/ja-jp/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) if err != nil { panic(err) } defer func() { if err = client.Disconnect(context.TODO()); err != nil { panic(err) } }() coll := client.Database("sample_restaurants").Collection("restaurants") // Creates a query filter to match documents in which the "cuisine" // is "Italian" filter := bson.D{{"cuisine", "Italian"}} // Retrieves documents that match the query filter cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } // Unpacks the cursor into a slice var results []Restaurant if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } // Prints the results of the find operation as structs for _, result := range results { output, err := json.MarshalIndent(result, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", output) } }
// results truncated ... { ... , "Name" : "Epistrophy Cafe", "RestaurantId": "41117553", "Cuisine" : "Italian", ... }, { ... , "Name" : "Remi", "RestaurantId": "41118090", "Cuisine" : "Italian", ... }, { ... , "Name" : "Sant Ambroeus", "RestaurantId": "41120682", "Cuisine" : "Italian", ... }, ...
1 つのドキュメントの検索
FindOne()
メソッドでは、 Context
型とクエリフィルターを渡す必要があります。 メソッドは、フィルターに一致する最初のドキュメントをSingleResult
タイプとして返します。
次の例では、コンテキスト、フィルター、 FindOneOptions
をFindOne()
メソッドに渡し、次のアクションを実行します。
一致するドキュメントは、
date_ordered
の値が 2009 年 11 月 30 日以前一致した最初の 2 つのドキュメントをスキップ
filter := bson.D{{"date_ordered", bson.D{{"$lte", time.Date(2009, 11, 30, 0, 0, 0, 0, time.Local)}}}} opts := options.FindOne().SetSkip(2) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err = coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Masala","rating":9,"date_ordered":"2009-11-12T05:00:00Z"}
FindOne()
を使用し、特定の ObjectId
値を使用してクエリを実行する例については、このページの「 ObjectId 別の 1 つの例を指定 」セクションを参照してください。
SingleResult
型からデータにアクセスする方法については、BSON ガイドの「アン マーシャリング」を参照してください。
ObjectId で 1 を検索する例
この例では、id
型の値を持つ 変数を定義し、ObjectId
id
を使用してクエリフィルターを指定しています。フィルターは、 id
変数に対応する_id
フィールド値を持つドキュメントと一致します。 この例では、 _id
値に基づいて次のドキュメントをクエリします。
{ _id: ObjectId('65170b42b99efdd0b07d42de'), item: "Hibiscus", rating : 4, date_ordered : 2009-12-18T05:00:00.000+00:00 }
次のコードでは、フィルターとFindOneOptions
インスタンスをパラメーターとしてFindOne()
メソッドに渡し、次のアクションを実行します。
指定された
ObjectId
値を持つドキュメントと一致する一致したドキュメントの フィールドと フィールドのみをプロジェクションする
Item
Rating
id, err := bson.ObjectIDFromHex("65170b42b99efdd0b07d42de") if err != nil { panic(err) } // Creates a filter to match a document that has the specified // "_id" value filter := bson.D{{"_id", id}} opts := options.FindOne().SetProjection(bson.D{{"item", 1}, {"rating", 1}}) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err = coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Hibiscus","rating":4}
注意
Go ドライバーは各ドキュメントの_id
フィールドに対して一意のObjectId
値を自動的に生成するため、 ObjectId
値は前のコード例と異なる場合があります。 _id
フィールドの詳細については、 ドキュメントの挿入 ページの [ _id フィールド ]セクションを参照してください。
1 ドキュメントの特定の例:完全なファイル
注意
セットアップ例
この例では、接続 URI を使用してMongoDBのインスタンスに接続します。MongoDBインスタンスへの接続の詳細については、MongoClient の作成 ガイドを参照してください。この例では、Atlasサンプルデータセットに含まれる sample_restaurants
データベースの restaurants
コレクションも使用します。「Atlas を使い始める」ガイドに従って、 MongoDB Atlasの無料階層のデータベースにロードできます。
次の例では、restaurants
コレクション内で name
の値が "Bagels N Buns"
である最初のドキュメントを検索して返します。
// Retrieves a document that matches a query filter by using the Go driver package main import ( "context" "encoding/json" "fmt" "log" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) // Creates a Restaurant struct as a model for documents in the restaurants collection type Restaurant struct { ID bson.ObjectID `bson:"_id"` Name string RestaurantId string `bson:"restaurant_id"` Cuisine string Address interface{} Borough string Grades []interface{} } func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") } var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/ja-jp/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) if err != nil { panic(err) } defer func() { if err = client.Disconnect(context.TODO()); err != nil { panic(err) } }() coll := client.Database("sample_restaurants").Collection("restaurants") // Creates a query filter to match documents in which the "name" is // "Bagels N Buns" filter := bson.D{{"name", "Bagels N Buns"}} // Retrieves the first matching document var result Restaurant err = coll.FindOne(context.TODO(), filter).Decode(&result) // Prints a message if no documents are matched or if any // other errors occur during the operation if err != nil { if err == mongo.ErrNoDocuments { return } panic(err) } output, err := json.MarshalIndent(result, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", output) }
// results truncated { "ID": "5eb3d668b31de5d588f42950", "Name": "Bagels N Buns", "RestaurantId": "40363427" "Address": [...], "Borough": "Staten Island", "Cuisine": "Delicatessen", "Grades": [...] }
動作の変更
FindOptions
または FindOneOptions
インスタンスを渡すことで、Find()
と FindOne()
の動作を変更できます。オプションを指定しない場合、ドライバーは各オプションのデフォルト値を使用します。
両方のタイプで一般的に使用されるオプションは、次の方法で構成できます。
方式 | 説明 |
---|---|
| The type of language collation to use when sorting results. Default: nil |
| The maximum number of documents to return. Default: 0 This option is not available for FindOneOptions . The
FindOne() method internally uses SetLimit(-1) . |
| The fields to include in the returned documents. Default: nil |
| The number of documents to skip. Default: 0 |
| The field and type of sort to order the matched documents. You can specify an ascending or descending sort. Default: none |
集計操作
集計操作を使用して、MongoDB からデータを取得して変換します。 Aggregate()
メソッドを使用して集計操作を実行します。
集計
Aggregate()
メソッドでは、 Context
タイプと集計パイプラインを渡すことが想定されています。 集計パイプラインは、ステージを通じてデータを変換する方法を定義します。 一部のステージは、ドキュメントの一致、フィールドの名前変更、値のグループ化です。
このメソッドでは、 Cursor
タイプの結果ドキュメントが返されます。 $matchステージを省略すると、パイプラインはコレクション内のすべてのドキュメントを使用して続行します。
カーソル内のデータにアクセスする方法については、「 カーソルからデータにアクセスする 」を参照してください。
動作の変更
Aggregate()
メソッドはオプションで、その動作を変更するために使用できるオプションを表すAggregateOptions
タイプを取ります。 オプションを指定しない場合、ドライバーは各オプションのデフォルト値を使用します。
AggregateOptions
タイプでは、次の方法でオプションを設定できます。
方式 | 説明 |
---|---|
| Whether to write to temporary files. Default: false |
| The number of documents to return in each batch. Default: none |
| Whether to allow the write to opt-out of document level validation. Default: false |
| The type of language collation to use when sorting results. Default: nil |
| The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Default: nil |
| An arbitrary string or document that allows you to trace the operation through the database profiler, currentOp, and logs. Default: "" |
| The index to use to scan for documents to retrieve. Default: nil |
| Specifies parameters for the aggregate expression, which improves command readability by separating the variables from the query text. Default: none |
例
次の例では、コンテキストと、次のアクションを実行する集計パイプラインを渡します。
並べ替えアイテムごとにレビューをグループ化
各項目の平均評価を計算
groupStage := bson.D{ {"$group", bson.D{ {"_id", "$item"}, {"average", bson.D{ {"$avg", "$rating"}, }}, }}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage}) if err != nil { panic(err) } // Prints the average "rating" for each item var results []bson.M if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Printf("%v had an average rating of %v \n", result["_id"], result["average"]) }
Sencha had an average rating of 8.5 Hibiscus had an average rating of 4 Masala had an average rating of 9
集計パイプラインの構築方法の詳細については、MongoDB サーバーのマニュアル ページ「集計 」を参照してください。
詳細情報
上記で説明されている操作の詳細については、次のガイドを参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。