MongoDBのScheme定義をProtocol Buffersで定義する in C#

MongoDBとProtobuf-netは相性が良いかもしれない?

protobuf-netのprotogenで出力したclassは
普通にそのままMongoDB Official C# DriverのSchemaとして利用できる。

.protoの内容

message Person {
  required int32 id = 1;
  required string name = 2;
  optional string email = 3;
}

出力したcsの内容

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// Generated from: test_type.proto
namespace test_type
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Person")]
  public partial class Person : global::ProtoBuf.IExtensible
  {
    public Person() {}
    
    private int _id;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"id", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    public int id
    {
      get { return _id; }
      set { _id = value; }
    }
    private string _name;
    [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"name", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string name
    {
      get { return _name; }
      set { _name = value; }
    }
    private string _email = "";
    [global::ProtoBuf.ProtoMember(3, IsRequired = false, Name=@"email", DataFormat = global::ProtoBuf.DataFormat.Default)]
    [global::System.ComponentModel.DefaultValue("")]
    public string email
    {
      get { return _email; }
      set { _email = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
  
}

動作テスト

Officialのサンプルコードをベースにテストしてみる。

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MongoDBProtoTest
{
	class Program
	{
		static void Main(string[] args)
		{
			MongoUrl url = MongoUrl.Create("mongodb://localhost:27017");
			var client = new MongoClient(url);
			var server = client.GetServer();
			var db = server.GetDatabase("Test");
			var col = db.GetCollection<test_type.Person>("Collection");

			var data = new test_type.Person() {
				name = "testname",
				id = 10,
				email = "test@example.com"
			};
			col.Insert(data);

			var q = Query<test_type.Person>.EQ( e => e.id, 10 );
			var d = col.FindOne(q);

			d.name = "mataro777";
			col.Save(d);

			var update = Update<test_type.Person>.Set(e => e.name, "mataro1234");
			col.Update(q, update);

			col.Remove(q);
		}
	}
}

まとめ

いろんなパターンを試した訳でないので、どこかでハマるかもしれないが、これはこれで一つの可能性を感じる結果となった。Import/ExportをProtocol Buffersを使って行うことが出来そう。

repeatedを使うとダメっぽい?? どうやら出力されるプロパティにsetが無いからみたい。