Search code examples
mongodbcookiesmongoosequery-performancejson-web-token

Should I use information stored in a cookie for indexing purposes?


I am creating my first major app, and I thought of a way to optimize query performance. I am not sure though whether I should go through with it.

Here is a description of my approach.

Every time a user account is created, that user is assigned a random number between 1 and 10, which is stored in their user document. The number is called a number-Id. Here is how the user schema will look like:

let User = new Schema({

/// I left out all the other fields for clairty sake
numberId: {
          type: Number,
          default: Math.floor(Math.random() * 11),
          index: true
    }
}

Every time a user creates a blogpost and post, their number-Id is referenced inside the document of that blogpost and post. This is to make querying much faster by indexing the users number-id. Here is how the document of a blogpost would look like in MongoD:

{ 
   "title": "my Blog Post",
   "_id": "ObjectId("594824b2828d7b15ecd7b6a5")",
   /// Here is the numberId of the user who posted the blogpost, it is added 
   /// to the document of the blogpost when it is created.
   "postersNumberId": 2
   /// the Id of the user who posted the blogpost
   "postersId": "59481f901f0c7d249cf6b050"
}

Let's say I want to get all the blogposts made by a specific user. I can optimize my query much faster by using the number-Id of the user in question as an index, given that their number-Id is referenced in all the blogposts and comment posts they make.

 BlogPost.find({postersId: user_id, postersNumberId: user.numberId});

It seems like this approach warrants that I store the users number-id in req.user in order for it to be readily available whenever I need it to optimize queries. So that means I would have to store the users data in a cookie via passport:

passport.serializeUser(function(user, done){
    done(null, user._id);
});

passport.deserializeUser(function(id, done) {
    User.findById(id, function (err, user){
        if (err || !user) return done(err, null);
        done(null, user);
    });
});

Given this approach, I could now use all the information stored in the cookie, particularly the numberId, to optimize queries that retrieve the comments and blogposts a user makes:

BlogPost.find({postersId: req.user_id, postersNumberId: req.user.numberId});

However, I am using json-web-tokens to authenticate the user rather than cookies. So I will have to use a cookie to store the number-Id for indexing purposes in addition to using JWT for authentication. I've heard, however, that having cookies is bad for scalability, so I am worried that storing the users number-Id in req.user will eventually impact performance.

Should I continue with this approach, or no? What are the performance implications?


Solution

  • In addition to authentication JWT has a payload, which can be used to store additional information within the generated token itself:

    var jwt = require('jsonwebtoken');
    
    var token = jwt.sign({
        data: {
            numberId: 7
        }
    }, 'jwtSecret', {
        expiresIn: '1h'
    });
    

    For retrieval:

    jwt.verify(token, 'jwtSecret', function(err, decoded) {
        if (err) {
            console.log(err)
        } else {
            console.log(decoded);
            //{ data: { numberId: 7 }, iat: 1498350787, exp: 1498354387 }
        }
    });