Pier-Olivier Marquis
Pier-Olivier Marquis

Reputation: 458

Mongoose find and findOne return entire collection

I have the code below in javascript and the database is already populated. Now when I use either find() or findOne(), Mongoose returns the entire collection of over 6000 entries. Why is the filter not happening?

var tickerIDSchema = new mongoose.Schema({
  ticker: String,
  name: String,
  exchange: String,
  "_id": false
});

var tickerListSchema = new mongoose.Schema({
  complete: [tickerIDSchema]
});

tickerListSchema.index(
  { "complete.ticker": 1, "complete.exhcange": 1 },
  { unique: true }
);

var tickerList = mongoose.model("tickerList", tickerListSchema);


tickerList.findOne({"complete.ticker": "BMO"}, function(err, data){

  console.log(data)
})

Result:

{ _id: 5a44452bb1dac235f039c66c,
  __v: 0,
  complete:
   [ { ticker: 'AAPL', name: 'Apple Inc.', exchange: 'Nasdaq' },
     { exchange: 'Amex',
       name: 'Altisource Asset Management Corp',
       ticker: 'AAMC' },
     { exchange: 'Amex',
       name: 'Almaden Minerals, Ltd.',
       ticker: 'AAU' },
     { exchange: 'Amex',
       name: 'Aberdeen Emerging Markets Smaller Company Opportunities Fund I',
       ticker: 'ABE' },
     { exchange: 'Amex',
       name: 'Acme United Corporation.',
       ticker: 'ACU' },
     { exchange: 'Amex', name: 'AeroCentury Corp.', ticker: 'ACY' },
     { exchange: 'Amex',
       name: 'Adams Resources & Energy, Inc.',
       ticker: 'AE' },
     { exchange: 'Amex', name: 'Ashford Inc.', ticker: 'AINC' },
     { exchange: 'Amex',
       name: 'Air Industries Group',
       ticker: 'AIRI' },
     ... 6675 more items ] }

Upvotes: 0

Views: 226

Answers (1)

Jason Warta
Jason Warta

Reputation: 450

You appear to have an extra layer of abstraction that is unnecessary.

This code effectively creates a document with a single attribute.

var tickerListSchema = new mongoose.Schema({
  complete: [tickerIDSchema]
});

The result is that you have a single document in your mongodb collection tickerList that contains all of your data within that single attribute, complete. Per the mongodb documentation (https://docs.mongodb.com/manual/reference/method/db.collection.findOne/), findOne should return the matching document. Because you are querying for a subdocument, the returned result is the parent document, which contains all of the data you have in your tickerIDSchema

To achieve your desired results, your mongoose code should probably look something like this.

var tickerIDSchema = new mongoose.Schema({
  ticker: String,
  name: String,
  exchange: String,
  "_id": false
});

tickerIDSchema.index(
  { "ticker": 1, "exchange": 1 },
  { unique: true }
);

var tickerList = mongoose.model("tickerList", tickerIDSchema);

tickerList.findOne({"ticker": "BMO"}, function(err, data){
  console.log(data)
})

Removing the tickerListSchema will allow you to query the tickerIDSchema directly. The findOne() query would appear as shown, and find() should operate as follows:

tickerList.find({}, function(err, data){
    console.log(data)
})

Upvotes: 1

Related Questions