Raphael Ahrens
Raphael Ahrens

Reputation: 992

How to insert a group of documents with a unique group id in MongoDB?

I have a collection in which some documents are in a group.

For example 2 and 3 are in a group:

{_id: 1, subject: "one",   groudId:  null}
{_id: 2, subject: "two",   groudId: "1234"} 
{_id: 3, subject: "three", groudId: "1234"}
{_id: 4, subject: "four",  groudId:  null}

Currently the groupId gets created at the same time when the documents of the group are created.

The Problem I have is that the design of our project currently creates the group_id on the client side and the clients then send it to the MongoDB.

I think that this can lead to the problem, that two clients generate the same groupId for two different groups. Especially since the grouId is at this moment a concatenation of the current time and the amount of time the client was running. (Don't ask me why, it wasn't my idea.)

So how can I create a unique id for the groups with MongoDB?

My first Idea was to just take the _id`` of the first task and make that thegroupId`. For example:

{_id: 1, subject: "one",   groudId:  null}
{_id: 2, subject: "two",   groudId:    2 } 
{_id: 3, subject: "three", groudId:    2 }
{_id: 4, subject: "four",  groudId:  null}

But _id gets created on insert so I can't set groudId on insert and have to do a later update.

So is this possible in any way without multiple inserts and/or updates? Or is there a scheme to create a unique group Id on the client?

Upvotes: 0

Views: 666

Answers (1)

Juan Carlos Farah
Juan Carlos Farah

Reputation: 3879

If you can change the way you generate the groupId fields, you can always use MongoDB's ObjectId() as an identifier. The possibility of generating duplicate ObjectId identifiers is extremely low, as explained in this post. You could then have your code do something like the following (in mongo shell syntax).

// First Group
> var groupId = ObjectId();
> db.collection.insert({ "subject": "two", "groupId": groupId });
> db.collection.insert({ "subject": "three", "groupId": groupId });

// Second Group
> var groupId = ObjectId();
> db.collection.insert({ "subject": "one", "groupId": groupId });
> db.collection.insert({ "subject": "four", "groupId": groupId });

If you want to reuse a groupId generated before, you can fetch it from the collection and then reuse it.

// Reuse First Group's ID
> var groupId = db.collection.findOne({ "subject": "two" })["groupId"];
> db.collection.insert({ "subject": "five", "groupId": groupId });  

As a side note, I would personally prefer to have a second collection groups where I would keep a document for each group and take the _id of that document as the identifier for the groupId field in your other collection. That way you can easily track the IDs for each group and any other information you want to store per group.

Upvotes: 2

Related Questions