It is possible to store uint32 values using a 32 bit BSON int, but it involves some tricks.
If you are using a C# class you have to tell the driver that you want to allow overflow. For example:
public class C
{
[BsonRepresentation(BsonType.Int32, AllowOverflow = true)]
public uint Id;
public string Data;
}
uint id = 2222222222; // too large for int32 but OK for uint32
var c = new C { Id = id, Data = "abc" };
collection.Insert(c);
If you are using lower level BsonDocuments you have to cast your uint id value to an int yourself:
uint id = 2222222223; // too large for int32 but OK for uint32
var document = new BsonDocument
{
{ "_id", (int) id },
{ "Data", "def" }
};
You also have to keep in mind that when you display large uint32 values in the mongo shell (values that have the high order bit set) they are going to display as negative numbers:
When these negative numbers are read back in to your C# program they will map back to the same uint32 they came from, but the fact that they display as negative numbers in the shell is going to make it difficult to work with your data in the shell.
So while it is possible to do this I wouldn't recommend it unless you really need to save space. It would be much easier to just choose a 64 bit integer key instead if a signed 32 bit integer doesn't have a large enough range for you, so I would recommend your option 1 (convert uint32 to long).