Reputation: 1647
Problem statement:
I have a collection in MongoDB that has a field with the type Int32. I would like to add a document to this collection. I need to increment the value by 1 for each insert as that field is indexed and must be unique.
Options:
Example:
{
_id: ....
index: 123,
open: true
}
await collection.InsertOneAsync(record.ToBsonDocument());
The new doc inserted should have index value of 124
Language:
C#
Questions:
Can you provide a sample code (C#) to achieve the first option?
Extra info:
I do not have access to the code of the other app (which keeps its own index number). So having another collection and adding an sequence resolver function will not work as this will trigger a change to the legacy app.
Upvotes: 4
Views: 11017
Reputation: 2867
I had to do this in a project using MongoDB C# Driver.
Here's what I did: I created a separated collection called Sequence, with the name and value of it and I also created a repository for it.
Here is the code of class Sequence:
public class Sequence
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
[BsonElement("_id")]
public string Id { get; set; }
public string SequenceName { get; set; }
public int SequenceValue { get; set; }
}
And now the code of the method to generate the sequence value:
public class SequenceRepository
{
protected readonly IMongoDatabase _database;
protected readonly IMongoCollection<Sequence> _collection;
public SequenceRepository(IMongoDatabase database)
{
_database = database;
_colecao = _database.GetCollection<Sequence>(typeof(Sequence).Name);
}
public int GetSequenceValue(string sequenceName)
{
var filter = Builders<Sequence>.Filter.Eq(s => s.SequenceName, sequenceName);
var update = Builders<Sequence>.Update.Inc(s => s.SequenceValue , 1);
var result = _colecao.FindOneAndUpdate(filter, update, new FindOneAndUpdateOptions<Sequence, Sequence> { IsUpsert = true, ReturnDocument = ReturnDocument.After });
return result.SequenceValue;
}
}
Finally I called this method before insert some document:
public void Inserir(Order order)
{
order.Code = new SequenceRepository(_database).GetSequenceValue("orderSequence");
_collection.InsertOne(order);
}
Upvotes: 1
Reputation: 1808
MongoDB has a default tutorial on how to achieve that here
1 - Create a counters collections and insert the id there:
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
2 - Create a custom function to retrieve the next value:
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
Use the getNextSequence
to retrieve the next value:
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Sarah C."
}
)
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Bob D."
}
)
Upvotes: 2
Reputation: 3424
You can create a Mongo Sequence in a separate collection counter
db.counter.insert({ _id: "mySeq", seq: 0 })
You can encapsulate sequence logic in a simple function
like this
function getNextMySeq(name) {
var ret = db.counter.findAndModify({
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
});
return ret.seq;
}
Now simply use the function call during the insert
db.collection.insert({
index: getNextMySeq("mySeq")
})
Upvotes: 0