23

I have a route set up that uses a model called Todo like below:

app.get('/api/todos', function(req, res) {
    Todo.find({},function(err, todos) {
        if (err)
            res.send(err);
        console.log("number of todos " + todos.length);
        res.json(todos); // return all todos in JSON format
    });
});

however, todos.length is always 0, as it do not find any results. When I run:

use test3
db.Todo.find() 

I am sure I have connected to the same db. I can see the connection in mongod console. My connection is inside config/db.js file:

module.exports = {
    url : 'mongodb://localhost/test3'
}

The connection in my server.js is as follows:

var db = require('./config/db');
mongoose.connect(db.url);

in Mongo Shell I get 1 result. I am expecting this result to be return by the find query. Is there something I have missed? I am using Mongoose 3.6

Cheers

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
user3539643
  • 241
  • 1
  • 2
  • 5
  • 2
    Are you sure you are connecting to the same database in your program as you are doing with the shell? Add your database connection code and an example of your connection with the shell to your question if you are not sure. – Neil Lunn Apr 16 '14 at 05:09
  • I have added some more info you requested – user3539643 Apr 16 '14 at 05:32
  • 2
    Also noting that mongoose pluralizes the model name by default as well as converts this to lowercase and other rules. So unless you are overriding this, mongoose is looking for a collection named "todos" which possibly does not exist. – Neil Lunn Apr 16 '14 at 05:36

2 Answers2

88

So what this very much looks like is that you have already created collections in an existing database and now you are trying to access these with mongoose models.

The problem is that mongoose uses some defaults which you may not be aware of, so the example you are showing from the shell is not the same as what mongoose is doing by default.

So you can either rename your collections to match what mongoose expects by default or change what mongoose does to match your existing names. In the latter case, you directly define the model names like so:

mongoose.model( "Todo", toDoSchema, "Todo" );

So the third argument to the method actually specifies the explicit name to use for the collection. Without this the assumed name under the default rules will be "todos".

Use either method in order yo make them match.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • i faced similar issue for 2 hours, i needed to add "s" after the name of my collection, omg... TY – PayteR Feb 17 '18 at 12:47
  • 1
    Can’t believe this answer is still true – Kartik Patel Aug 18 '20 at 13:16
  • I didn't even touch my be/mongo/fe, nothing at all and after more than 30 days it stopped returning results (returned an empty array). After several hours of agony, I reached this thread. I added the third argument and it worked. I can't understand how this is not yet fixed. Anyway, future readers, just add the third argument and don't trust mongoose. – Rounak Jain Jun 11 '21 at 03:02
  • @RounakJain I am facing the same problem right now (getting a blank response), and I tried adding the 3rd argument, but the problem remains. And yes, I did not touch my code either; it just stopped working today! – Sohail Saha Aug 21 '21 at 04:54
0

I faced this exact issue, I defined the Model for an already existing collection in MongoDB and to stop Mongoose from producing a collection name in plural I used this explicit collection option. Mistakenly I wrote Collection and this halted the results. So be careful while using explicit options, they are case sensitive.

DevX
  • 17
  • 1
  • 4