将复合ID序列化为二进制

时间:2012-10-18 18:52:25

标签: c# mongodb serialization mongodb-.net-driver

我有以下代表复合_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个字段的upsert语句,但速度很可怕。所以我接下来要做的是使用p0,BinarySerialized(p1:p7)作为_id。我的用例允许我连接这些字段而没有问题。

序列化p1-p7的最佳方法是什么? C#的序列化器,还是BSON的?

对于记录,upsert:

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);

2 个答案:

答案 0 :(得分:2)

使用upsert查看已编辑的问题,您应该重写查询,以便服务器可以利用_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索引。

答案 1 :(得分:1)

我首先要研究为什么你的upsert如此缓慢。它可能只是查询部分的编写方式,在这种情况下,更改Id可能没有帮助。

如果你想将p1到p7组件编码为二进制字节,我建议你定义你的Id类:

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

但是你必须在某处编写一些辅助方法或属性来处理打包和解包字节。我不会使用任何类型的串行器,但一次只能打包4个字节(所以p1to7的长度为28个字节)。