Reputation: 18249
I have the following test class that represents a composite _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; }
}
The data class:
private sealed class MdbData
{
[BsonId]
public Id _Id;
public List<string> data = new List<string>();
}
I wrote an upsert statement that uses all 8 fields, but the speed was horrific. So what I want to do next is use p0, BinarySerialized(p1:p7) as the _id. My use case allows me to concatenate these fields without issue.
What is the best way to serialize p1-p7? C#'s serializer, or BSON's?
For the record, the 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);
Upvotes: 1
Views: 429
Reputation: 12187
Seeing your edited question with the upsert, you should rewrite your query so that the server can take advantage of the _id index. The easiest way is to use the typed Query builder:
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);
If you write the query checking each component of the _id separately the server can't use the _id index.
Upvotes: 2
Reputation: 12187
I would start by investigating why your upsert was so slow. It might just be the way the query part was written, in which case changing the Id might not help.
If you do want to encode your p1 through p7 components as binary bytes, I would recommend you define your Id class like this:
public sealed class Id
{
public int p0 { get; set; }
public byte[] p1to7 { get; set; }
}
But then you have to write some helper methods or properties somewhere to deal with packing and unpacking the bytes. I wouldn't use any kind of serializer, but just pack the ints 4 bytes at a time (so p1to7 would be 28 bytes long).
Upvotes: 1