Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I validate DBRefs in a MongoDB collection?

Assuming I've got a MongoDB instance with 2 collections - places and people.

A typical places document looks like:

{
    "_id": "someID"
    "name": "Broadway Center"
    "url": "bc.example.net"
}

And a people document looks like:

{
    "name": "Erin"
    "place": DBRef("places", "someID")
    "url":  "bc.example.net/Erin"
}

Is there any way to validate the places DBRef of every document in the people collection?

like image 824
noamt Avatar asked Mar 11 '13 14:03

noamt


People also ask

How does MongoDB verify data?

MongoDB doesn't have constraints or triggers so the application has to validate the data. You can also write Javascript scripts that check once a day or more if there is invalid data. You can use this to check the quality of the business logic of your application.

Which fields are in DBRefs?

DBRefs are made up of three fields: $ref: This field specifies the collection of the referenced document. $id: This field specifies the _id field of the referenced document. $db: This is an optional field and contains the name of the database in which the referenced document lies.

What is @dbref in MongoDB?

DBRefs are references from one document to another using the value of the first document's _id field, collection name, and, optionally, its database name, as well as any other fields. DBRefs allow you to more easily reference documents stored in multiple collections or databases.


2 Answers

There's no official/built-in method to test the validity of DBRefs, so the validation must be performed manually.

I wrote a small script - validateDBRefs.js:

var returnIdFunc = function(doc) { return doc._id; };

var allPlaceIds  = db.places.find({}, {_id: 1} ).map(returnIdFunc);

var peopleWithInvalidRefs = db.people.find({"place.$id": {$nin: allPlaceIds}}).map(returnIdFunc);

print("Found the following documents with invalid DBRefs");
var length = peopleWithInvalidRefs.length;
for (var i = 0; i < length; i++) {
    print(peopleWithInvalidRefs[i]);
}


That when run with:

mongo DB_NAME validateDBRefs.js


Will output:

Found the following documents with invalid DBRefs

513c4c25589446268f62f487

513c4c26589446268f62f48a

like image 50
noamt Avatar answered Sep 21 '22 17:09

noamt


you could add a stored function for that. please note that the mongo documentation discourages the use of stored functions. You can read about it here

In essence you create a function:

db.system.js.save(
   {
     _id : "myAddFunction" ,
     value : function (x, y){ return x + y; }
   }
);

and once the function is created you can use it in your where clauses. So you could write a function that checks for the existence of the id in the dbRef.

like image 30
Micha Roon Avatar answered Sep 21 '22 17:09

Micha Roon