C#からMongoDBを触るのを試してる。何となく検索して出てくる日本語の情報が古い気がする。 MongoDB.DriverはNuGetで取れる「2.2.3」を使用。まずは、基本的なとろこから。

  • 接続
//接続文字列(MongoDBをインストールしてデフォルトのままの場合)
string connectionString = "mongodb://localhost";
//MongoDBに接続
MongoClient client = new MongoClient(connectionString);
//データベースを選ぶ(use foo)
var database = client.GetDatabase("foo");
//コレクションを決める
var collection = database.GetCollection("bar");
//とりあえず最初の一件を取得()
var finddocument = collection.Find(new BsonDocument()).FirstOrDefault();
  • CRUD

↓ためし用のクラス。

public class Heroes
{
    public ObjectId Id { get; set; }
    public string ヒーロー { get; set; }
    public string 所属 { get; set; }
}

CRUD

public void TestCRUD()
{
    //接続文字列(MongoDBをインストールしてデフォルトのままの場合)
    string connectionString = "mongodb://localhost";
    //MongoDBに接続
    MongoClient client = new MongoClient(connectionString);
    //データベースを選ぶ(use foo)
    var database = client.GetDatabase("foo");
    //コレクションを決める
    var collection = database.GetCollection("heroes");

    /////////////////////////////////////////////////////////////
    //1件作成
    var oneDocument = new Heroes
    {
        ヒーロー = "ヤン",所属="同盟"
    };
    collection.InsertOne(oneDocument);

    /////////////////////////////////////////////////////////////
    //複数件作成
    List documents = new List();
    documents.Add(new Heroes { ヒーロー = "ラインハルト", 所属 = "帝国" });
    documents.Add(new Heroes { ヒーロー = "メルカッツ", 所属 = "帝国" });
    documents.Add(new Heroes { ヒーロー = "キルヒアイス", 所属 = "帝国" });
    collection.InsertMany(documents);

    /////////////////////////////////////////////////////////////
    //Find
    var filterbuilder = Builders.Filter;
    var filter = filterbuilder.Eq("所属", "同盟");
    var findDocuments = collection.Find(filter);
    foreach (var tmp in findDocuments.ToList())
    {
        Console.WriteLine(tmp.ヒーロー);
    }
    //結果 ⇒ ヤン

    /////////////////////////////////////////////////////////////
    //更新
    var updatefilter = filterbuilder.Eq("ヒーロー", "メルカッツ");
    var updateElem = Builders.Update.Set("所属", "同盟");
    var result = collection.UpdateMany(updatefilter, updateElem);//マッチした中の先頭1件のみ削除の場合はUpdateOne
    if (result.IsModifiedCountAvailable)
    {
        Console.WriteLine("【更新結果】マッチ:{0}件 更新:{1}件", result.MatchedCount, result.ModifiedCount);
    }
    findDocuments = collection.Find(filter);
    foreach (var tmp in findDocuments.ToList())
    {
        Console.WriteLine(tmp.ヒーロー);
    }
    //結果 ⇒ ヤン メルカッツ

    /////////////////////////////////////////////////////////////
    //削除
    var delfilter = Builders.Filter.Eq("ヒーロー", "ヤン");
    var delresult = collection.DeleteMany(delfilter);//マッチした中の先頭1件のみ削除の場合はDeleteOne
    Console.WriteLine("削除件数:{0}", delresult.DeletedCount);

    findDocuments = collection.Find(filter);
    foreach (var tmp in findDocuments.ToList())
    {
        Console.WriteLine(tmp.ヒーロー);
    }
    //結果 ⇒ メルカッツ
}

試してみて、分かった内容は次。

  1. ObjectIDは必須(無い場合、追加はできてもFindで落ちる)
  2. コレクション作った後に、クラスにプロパティを追加してもOK
  3. コレクション作った後に、クラスのプロパティを削るとアウト

とりあえず、ObjectIDは必須ですね。クラス定義で使う場合は無いとまず動かない。 あとはデータ作った後に、プロパティ追加してもFind出来た。追加したプロパティがフィールドに無い場合はもちろんNullでかえってくるけども。クラスの拡張はいけそー。コードファースト的なノリでいけそー。ただ、やっぱプロパティの削除はダメね。まぁ、当たり前か。

で、見かけるサンプルって、こんな感じでクラス定義して使うのがほとんど。 でもそれって、
スキーマレスじゃないと思うんだ
MongoDBの利点なのかどーかは色々あるだろーけどもスキーマレスなのが特徴だったよーな。 とゆーわけでスキーマレスにCRUDしましょ。まぁ、公式のQuickTourがスキーマレスでやってるからそれを見ろってことなのかしら。

次は、スキーマレスの操作と、性能回りの実験やる。