Dan
Dan

Reputation: 1986

How can I create unique IDs for embedded documents in MongoDB?

So I need to reference particular subdocuments uniquely from items in my collection. For instance:

User = {
    'name': 'jim',
    'documents: [
        {'id': 0001, 'title': "My document"},
        {'id': 0002, 'title': "My second document!"},
    ]
}

So I need to be able to auto-create IDs for new documents, preferably not at the application level (since there will be race conditions in the actual development scenario).

Is there a way to use mongo's autogenerated ObjectId (used in the _id field at the collection level), or something similar?

Upvotes: 42

Views: 30580

Answers (6)

toto11
toto11

Reputation: 1582

With mongoengine create a ObjectId in an embedded document like this:

from bson.objectid import ObjectId

class Address(EmbeddedDocument):
    _id = ObjectIdField( required=True, default=ObjectId )
    street = StringField()

Upvotes: 8

Emilia Apostolova
Emilia Apostolova

Reputation: 1787

And this is how you can do it in python (pymongo):

from pymongo import MongoClient
import bson

client = MongoClient('mongodb://localhost:27017/')
db = client.test_db

result=db.users.insert_one({'name': 'jim',
    'documents': [
        {'_id': bson.objectid.ObjectId(), 'title': "My document"},
        {'_id': bson.objectid.ObjectId(), 'title': "My second document!"},
    ]})

print list(db.users.find({}))

Upvotes: 3

Asfand Qazi
Asfand Qazi

Reputation: 6875

And here's how to do it in Clojure, assuming the use of congomongo:

(import org.bson.types.ObjectId)
(str (ObjectId.)) ; => "12345xxxxx"

Upvotes: 0

deepwell
deepwell

Reputation: 20861

In Meteor, on the server, use:

new Meteor.Collection.ObjectID(hexString);

See: http://docs.meteor.com/#collection_object_id

Upvotes: 3

Eve Freeman
Eve Freeman

Reputation: 33155

All drivers have functionality for generating ObjectIds.

In the shell you just do new ObjectId():

> db.test.insert({x:new ObjectId()});
> db.test.find();
{ "_id" : ObjectId("4f88592a06c05e4de90d0bc1"), "x" : ObjectId("4f88592a06c05e4de90d0bc0") }

In Java it's new ObjectId() as well. See the API docs for your driver to see the specific syntax.

Upvotes: 14

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230326

Yes, using mongo's ObjectId is the way to go. The only thing is: you have to generate them yourself, in the application code. They are meant to be globally unique, different workers won't generate two identical ObjectIds, so there's no race condition in that sense.

All official drivers should provide a way to generate ObjectId. Here's how it is in Ruby:

oid = BSON::ObjectId.new

Upvotes: 34

Related Questions