4

I have seen a number of ways of finding documents in mongoDB such that there is no performance hit, i.e. you don't really retrieve the document; instead you just retrieve a count of 1 or 0 if the document exists or not.

In mongoDB, one can probably do:

db.<collection>.find(...).limit(1).size()

In mongoose, you either have callbacks or not. But in both cases, you are retrieving the entries rather than checking the count. I simply want a way to check if a document exists in mongoose — I don't want the document per se.

EDIT: Now fiddling with the async API, I have the following code:

for (var i = 0; i < deamons.length; i++){
    var deamon = deamons[i]; // get the deamon from the parsed XML source
    deamon = createDeamonDocument(deamon); // create a PSDeamon type document
    PSDeamon.count({deamonId: deamon.deamonId}, function(error, count){ // check if the document exists
        if (!error){
            if (count == 0){
                console.log('saving ' + deamon.deamonName);
                deamon.save() // save
            }else{
                console.log('found ' + deamon.leagueName);
            }
        }
    })
}
p0lAris
  • 4,750
  • 8
  • 45
  • 80

3 Answers3

4

You have to read about javascript scope. Anyway try the following code,

for (var i = 0; i < deamons.length; i++) {
    (function(d) {
        var deamon = d
        // create a PSDeamon type document
        PSDeamon.count({
            deamonId : deamon.deamonId
        }, function(error, count) {// check if the document exists
            if (!error) {
                if (count == 0) {
                    console.log('saving ' + deamon.deamonName);
                    // get the deamon from the parsed XML source
                    deamon = createDeamonDocument(deamon);
                    deamon.save() // save
                } else {
                    console.log('found ' + deamon.leagueName);
                }
            }
        })
    })(deamons[i]);
}

Note: Since It includes some db operation, I am not tested.

HILARUDEEN S ALLAUDEEN
  • 1,722
  • 1
  • 18
  • 33
  • 1
    Thanks. For now, I just did: `deamons.forEach(function(deamon){`. This works but I am wondering if this is a good way to do it? And thanks, I'll read up on javascript scope. – p0lAris Oct 29 '13 at 21:19
  • @flippex, You can also use "forEach". Of course, "forEach" is very straight forward and good approach as well – HILARUDEEN S ALLAUDEEN Oct 29 '13 at 21:22
3

I found it simpler this way.

let docExists = await Model.exists({key: value});
console.log(docExists);

Otherwise, if you use it inside a function, make sure the function is async.

let docHandler = async () => {
   let docExists = await Model.exists({key: value});
   console.log(docExists);
};
Mehedi
  • 281
  • 3
  • 5
1

You can use count, it doesn't retrieve entries. It relies on mongoDB's count operation which:

Counts the number of documents in a collection. 
Returns a document that contains this count and as well as the command status. 
Kai Sternad
  • 22,214
  • 7
  • 47
  • 42
  • Is this an async call or a synchronous call, as I need to return this to some other function? – p0lAris Oct 29 '13 at 20:33
  • @flippex17 this is an asychronous call, you need to chain your calls. See http://stackoverflow.com/questions/17181248/making-mongoose-js-queries-run-synchronously – Kai Sternad Oct 29 '13 at 20:44
  • I just added some code and I would really appreciate if you could help figure out the issue. (I am really new to `javascript` and `Node.js`). Thanks! – p0lAris Oct 29 '13 at 21:01
  • Looks like `forEach` is the way to go? – p0lAris Oct 29 '13 at 21:12