sql >> データベース >  >> NoSQL >> MongoDB

MongoDbcsharpドライバーを使用してタイプが変更された場合のフィールドの逆シリアル化

    いくつかのことが起こっています。主なものは、タイプに関係なく入力を消費する必要があることです。そうしないと、逆シリアル化プロセスが同期しなくなります。 nullを処理し、ZipCodesを文字列として書き込む、ZipCodeSerializerと呼ばれるカスタムシリアライザーを作成するシナリオをテストしましたが、入力時に文字列またはintのいずれかを受け入れ、intを文字列に変換します。

    このクラスを使用してテストしました:

    public class Address
    {
        public ObjectId Id;
        public string ZipCode;
    }
    

    そして、これは私が書いたカスタムシリアライザーです:

    public class ZipCodeSerializer : BsonBaseSerializer
    {
        public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
        {
            var bsonType = bsonReader.CurrentBsonType;
            switch (bsonType)
            {
                case BsonType.Null:
                    bsonReader.ReadNull();
                    return null;
                case BsonType.String:
                    return bsonReader.ReadString();
                case BsonType.Int32:
                    return bsonReader.ReadInt32().ToString();
                default:
                    var message = string.Format("ZipCodeSerializer expects to find a String or an Int32, not a {0}.", bsonType);
                    throw new BsonSerializationException(message);
            }
        }
    
        public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
        {
            if (value == null)
            {
                bsonWriter.WriteNull();
            }
            else
            {
                bsonWriter.WriteString((string)value);
            }
        }
    }
    

    カスタムシリアライザーが接続されていることを確認する必要があります。これは次のように実行できます:

    BsonClassMap.RegisterClassMap<Address>(cm =>
        {
            cm.AutoMap();
            cm.GetMemberMap(a => a.ZipCode).SetSerializer(new ZipCodeSerializer());
        });
    

    これで、AddressクラスのZipCodeフィールドがカスタムシリアライザーによって処理されるようになります。

    BsonDocumentを使用していくつかのテストデータを作成し、テストコレクションに保存されている特定のバージョンのデータを簡単に強制できるようにしました。

    collection.Drop();
    collection.Insert(new BsonDocument());
    collection.Insert(new BsonDocument("ZipCode", BsonNull.Value));
    collection.Insert(new BsonDocument("ZipCode", "12345"));
    collection.Insert(new BsonDocument("ZipCode", 56789));
    

    mongoシェルを使用したドキュメントは次のようになります。

    > db.test.find()
    { "_id" : ObjectId("4f871374e447ad238040e346") }
    { "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
    { "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
    { "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : 56789 }
    >
    

    したがって、一部のZipCodeは文字列であり、一部はintであることがわかります(nullもスローされます)。

    そしてこれが私のテストコードです:

    foreach (var document in collection.FindAll())
    {
        Console.WriteLine(document.ToJson());
    }
    

    そして、テストコードの実行の出力は次のとおりです。

    { "_id" : ObjectId("4f871374e447ad238040e346"), "ZipCode" : null }
    { "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
    { "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
    { "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : "56789" }
    Press Enter to continue
    

    データベース内のintであった郵便番号が文字列になっていることに注意してください。

    私のテストプログラムの完全なソースコードは、次のURLで入手できます。

    http://www.pastie.org/3775465




    1. MongoDBの並べ替えは、インデックス付きフィールドでも非常に低速です

    2. マングースドキュメントインスタンスをコピー/クローンする最も簡単な方法は?

    3. 2つのオブジェクト配列を比較し、それらに共通の要素があるかどうかを確認します

    4. MongoDBでの結果を制限しますが、それでも完全なカウントを取得しますか?