1

複合_idを表す次のテストクラスがあります。

private sealed class Id
{
    public int p0 { get; set; }
    public int p1 { get; set; }
    public int p2 { get; set; }
    public int p3 { get; set; }
    public int p4 { get; set; }
    public int p5 { get; set; }
    public int p6 { get; set; }
    public int p7 { get; set; }
}

データクラス:

private sealed class MdbData
{
    [BsonId]
    public Id _Id;
    public List<string> data = new List<string>();
}

8つのフィールドすべてを使用するアップサートステートメントを作成しましたが、速度はひどいものでした。したがって、次に実行したいのは、_idとしてp0、BinarySerialized(p1:p7)を使用することです。私のユースケースでは、これらのフィールドを問題なく連結できます。

p1-p7をシリアル化する最良の方法は何ですか?C#のシリアライザー、またはBSONの?

記録のために、アップサート:

col.Update(Query.And(
    Query.EQ("_id.p0", doc.p0),
    Query.EQ("_id.p1", doc.p1),
    Query.EQ("_id.p2", doc.p2),
    Query.EQ("_id.p3", doc.p3),
    Query.EQ("_id.p4", doc.p4),
    Query.EQ("_id.p5", doc.p5),
    Query.EQ("_id.p6", doc.p6),
    Query.EQ("_id.p7", doc.p7)),
    Update.Push("data", doc.data),
    UpdateFlags.Upsert);
4

2 に答える 2

2

編集した質問をアップサートで確認したら、サーバーが_idインデックスを利用できるように、クエリを書き直す必要があります。最も簡単な方法は、型付きクエリビルダーを使用することです。

var query = Query<MdbData>.EQ(x => x._Id, doc._Id);
var update = Update<MdbData>.Push(x => x.data, doc.data);
collection.Update(query, update, UpdateFlags.Upsert);

_idの各コンポーネントを個別にチェックするクエリを作成すると、サーバーは_idインデックスを使用できなくなります。

于 2012-10-21T03:29:59.340 に答える
1

まず、アップサートが非常に遅い理由を調査します。クエリ部分が記述された方法である可能性があります。その場合、IDを変更しても効果がない可能性があります。

p1からp7コンポーネントをバイナリバイトとしてエンコードする場合は、Idクラスを次のように定義することをお勧めします。

public sealed class Id
{
    public int p0 { get; set; }
    public byte[] p1to7 { get; set; }
}

ただし、バイトのパックとアンパックを処理するために、ヘルパーメソッドまたはプロパティをどこかに作成する必要があります。私はどんな種類のシリアライザーも使用しませんが、一度に4バイトずつintをパックするだけです(したがって、p1to7は28バイトの長さになります)。

于 2012-10-19T18:08:58.197 に答える