11

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?

noamt
  • 7,397
  • 2
  • 37
  • 59
  • Only by manually picking out the documents and querying for the next collections document existance. – Sammaye Mar 11 '13 at 15:05
  • 3
    Slightly off-topic but make sure you need DBRef rather than simply storing a document ID. DBRef is only a good choice if you are not sure in which logical database the document is that is being referred to. Both options require manual querying for the referred document (although some higher level libraries will do that for you). – Remon van Vliet Mar 11 '13 at 15:21
  • Thanks for the tip; DBRefs are in-fact required. – noamt Mar 12 '13 at 07:33

2 Answers2

10

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

noamt
  • 7,397
  • 2
  • 37
  • 59
1

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.

Micha Roon
  • 3,957
  • 2
  • 30
  • 48
  • Thanks for the suggestion. Because it's an operation that won't be executed very often, I'll just write a script and manually evaluate it. – noamt Mar 12 '13 at 13:08