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 个字段的 upsert 语句,但速度非常可怕。所以我接下来要做的是使用 p0, BinarySerialized(p1:p7) 作为_id。我的用例允许我毫无问题地连接这些字段。

序列化 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

使用 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 索引。

于 2012-10-21T03:29:59.340 回答
1

我将首先调查您的 upsert 为何如此缓慢。这可能只是查询部分的编写方式,在这种情况下更改 Id 可能无济于事。

如果您确实想将 p1 到 p7 组件编码为二进制字节,我建议您像这样定义您的 Id 类:

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

但是你必须在某处编写一些辅助方法或属性来处理打包和解包字节。我不会使用任何类型的序列化程序,而是一次将整数打包 4 个字节(因此 p1to7 的长度为 28 个字节)。

于 2012-10-19T18:08:58.197 回答