9

What's the difference between:

{
   _id: ObjectId("507f191e810c19729de860ea")
}

and

{
   _id: "507f191e810c19729de860ea"
}

I can't seem to find anything on the matter.

It puzzles me because when you insert using JavaScript it'll use the ObjectId("507f191e810c19729de860ea") format. But if you use the C# driver it'll use the "507f191e810c19729de860ea" format.

The string format seems like the better choice as it uses less space.

Snæbjørn
  • 10,322
  • 14
  • 65
  • 124
  • What do you mean that the C# driver is using the "String" format? – WiredPrairie Apr 12 '13 at 20:38
  • It might just be a derp :). I'm using `cm.IdMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);` and `ObjectId.GenerateNewId().ToString();` which causes it to be of the latter. Guess I'll try out `ObjectIdGenerator.Instance` next :) - I had a lot of troubles getting it to work, so tried a lot of stuff. – Snæbjørn Apr 12 '13 at 20:44

2 Answers2

9

ObjectIDs are a 12-byte BSON object ID (it requires 24 to display as hex, since you need two hex characters to encode a byte value). The string is a full 24 bytes. See the ObjectID specification for specifics.

That said, you can use anything you want for your _id field, but it's recommended that you stick to a consistent scheme - either use all strings (as well as strings in cases that you reference other documents from foreign keys) or use all ObjectIDs. It is conventional to use ObjectIDs, but as long as you have a fully consistent scheme, you shouldn't have significant problems with it.

Chris Heald
  • 61,439
  • 10
  • 123
  • 137
  • Makes sense. Any chance you know why the C# driver is using the string format instead of the smaller ObjectId? – Snæbjørn Apr 12 '13 at 20:24
  • No idea, but the driver probably contains an ObjectID factory somewhere that you can use. – Chris Heald Apr 12 '13 at 20:29
  • What Christ said is exactly right. In mongo ObjectIDs are a 12-byte BSON object ID that is also based a clock, its almost impossible to have the same object id. for more info: http://bsonspec.org/#/specification – lciamp Apr 13 '13 at 05:21
2

The biggest difference is of course the destination storage and how you interact with it in the API. (I wrote about something similar here on StackOverflow as it related to DBRefs).

When using the C# driver (and plain-old-C#-objects), if you want to force the Id to be stored as an ObjectId, you may need to use the BsonRepresentationAttribute:

public class StackOverflow
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string Name { get; set; }
}

Or if you want to keep your classes free of MongoDB attributes:

BsonClassMap.RegisterClassMap<StackOverflow>(cm => {
    cm.AutoMap();
    cm.IdMemberMap.SetRepresentation(BsonType.ObjectId);
});

I have used this technique a number of times successfully. When I don't explicitly set the _id to a custom ID (a custom key of some sort), I always use the ObjectId format as it's relatively small and unique (and is smaller than a UUID and also embeds creation time which is really nice sometimes).

Community
  • 1
  • 1
WiredPrairie
  • 58,954
  • 17
  • 116
  • 143