Mongoose - Searching Schema via findOne() unsuccessfully

1.1k views Asked by At

In setting up a sessionStore via MongoDB for express-session, I'm having a little trouble using the findOne() function to verify that a user's information is valid and recent.

var session = require('express-session');
var mongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');

var Schema = mongoose.Schema;
var Session = mongoose.model('session', new Schema({
    sid : String,
    username : String,
    email : String
}));

...

The trick is, however, that express-session and connect-mongo are responsible for managing the writes to the database.

app.use(session({
    secret: 'secretsquirrel',
    resave: true,
    saveUninitialized: true,
    store: new mongoStore({
        mongoseConnection: mongoose.connection,
        host: '127.0.0.1',
        port: '27017',
        db: 'testdb',
        collection: 'collectionName'
    })
}));

Now, this appears to be working as it should, as documents are entered into the collection I have specified. Returning data from the collection yields the following:

{  
   "_id":"sdBYsdflAsdfyWPPneV-hrC2xsXP",
   "session":"
   {
       \"cookie\":
       {
        \"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"
       },
       \"email\":\"[email protected]\",
       \"username\":\"testuser\",
       \"sid\":\"f59106e845e11df8c3413b5f1f80ee01e876526bc3c0d05\",
   }",
   "expires":   ISODate(DateHere)
}

Where the problem appears to be that in the database, or via Mongoose, it doesn't seem to matter how I attempt to query for the SID, I return no results using any of the following:

Via Mongo:

db.collectionName.findOne({ session.sid: "sid" })
db.collectionName.findOne({ "session.sid": "sid" })
db.collectionName.findOne({ "session": { "\"sid\"": "sid" } })

Via Mongoose (NodeJS)

Session.findOne({ sid: req.session.sid }, function(err, data) {...});
Session.findOne({ "sid": req.session.sid }, function(err, data) {...});
Session.findOne({ "\"sid"\"": "\"" + req.session.sid + "\"" }, function(err, data) {...});

The stumper is, how is it in both instances I am unable to return any data that I have verified is in the collection? Do I need to account for the escaped quotes returned in the document as I have been trying to do, or is that merely output via the mongo shell?

Are there any steps I am missing for searching this data correctly? A fresh set of eyes would be greatly appreciated!

Solution:

vinagreti pointed out that the data being saved to my collections were not Objects, but rather plaintext.

By referring to connect-mongo's documentation, there is an extra option for stringify. This setting stringify's and serializes the data saved from the session into the database. Considering that express-session already produces a JSON object, using stringify() makes it unsearchable within the collection.

All that was needed was to add stringify: false to my mongoStore settings like so:

store: new mongoStore({
        mongoseConnection: mongoose.connection,
        host: '127.0.0.1',
        port: '27017',
        db: 'testdb',
        collection: 'collectionName',
        stringify: false
    })

And then voila! Everything saved to the collection is now an object and searchable! Thank you vinagreti for helping point out the problem! Please upvote his answer!

1

There are 1 answers

8
Bruno João On BEST ANSWER

You are saving your session object as plain text. because of that you cannot search as an object.

Ensure that the schema of the "father" collection have the session field as type '{}' (Object) like: Father = {session: { type: {} }}

If it not work, you can try the folowing:

You can change the way you are saving the session object, saving it as an object and not as an plain text.

Or, you can search the session with a regex, trying to find the sid on the session field like:

db.user.findOne({session: /.*f59106e845e11df8c3413b5f1f80ee01e876526bc3c0d05.*/});