Using PHP and MongoDB, i have a collection called users and another one called forms in the same DB.
I am using the Mongodb ObjectID as user identifier for the documents in the forms collection, saving the users ObjectId as uid on each forms document.
I am going to create an index of the uid field in the forms collection, but my question is how i should save the users Objectid?
As of now I am saving it as a normal string like (simplified)
$collection->insert( array('formName'=>'The name','uid'=>'CURRENT_USERS_ObjectId_AS_string') );
Does this seem logic or is best practice in this case to create a Mongodb ObjectID for uid like
$collection->insert( array('formName'=>'The name','uid'=> new MongoId('CURRENT_USERS_ObjectId_AS_string')) );
The use of manual references is perfectly fine - recommended even. Only use DbRefs if they offer specific benefits - such as permitting automatic de-referencing (a mongo script or php code can automatically know that foo points at collection x, with id y [in database z]).
However avoid type juggling.
Having what is effectively a foreign key in one collection, and it being a different type from that of the collection it's pointing at is a bad design. Type juggling is something to eliminate from development in general, not introduce.
Code like this ran on the db should work:
form = db.forms.findOne();
user = db.users.findOne({_id: form.user_id});
And it shouldn't matter what type the users collection _id field is. With the schema in the question this code becomes:
form = db.forms.findOne();
user = db.users.findOne({_id: new MongoId(form.user_id)});
In and of itself, that's not a huge difference, but it means you have to think/remember to convert these references and it becomes problematic if/when a collection is created which uses a different type - it introduces inconsistencies.
Consider the following:
> school = db.schools.insert({_id: 123, name: "my school"});
> userId = new ObjectId();
> db.users.insert({_id: userId, name: "Me"});
> db.forms.insert({user_id: userId, school_id: 123});
Let's say that the school id is a unique code. if there's no possibility it could change - it's appropriate and a good idea to use as the _id field. Now, the school id and the user id are different types:
> db.forms.findOne();
{
"_id" : ObjectId("508940370392baf87e68e31d"),
"user_id" : ObjectId("5089401c0392baf87e68e31b"),
"school_id" : 123
}
If they are stored as-is, it's still possible to be completely ignorant of these different types in queries:
form = db.forms.findOne();
school = db.schools.findOne({_id: form.school_id});
user = db.users.findOne({_id: form.user_id});
If different types are used that means that it becomes necessary to think "with this collection I need to convert the string to an ObjectId, but with this one I must not".
That's a problem that could have been avoided, but instead - it was introduced.
Now I am not familiar with PHP but the schema design that you have suggested is good.I am using a similar structure for my c# implementation.Just to be clear here is a sample of my schema design
Account Class
public ObjectId Id{get;set;}
public string Email {get;set}
public string Password{get;set;}
User Class
public ObjectId Id{get;set;}
public string AccountId {get;set}//refers to the ID in the account.
Now if I want to query an account for any user I can simply query it using the accountId in the user class.
MongoDb calls this referencing technique as manual referencing and this is also the one that it recommends here is the link http://docs.mongodb.org/manual/applications/database-references/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With