MongoDB: Error setting TTL index on collection : s

2019-01-21 17:17发布

问题:

Initially this error message started appearing very infrequently, but started to appear more regularly and now appears 4/5 times I run my application.

I'm handling my session store with Mongo and as I understand it, the TTL index is used to make the session data expire.

/home/dan/dev/audio-wave/node_modules/connect-mongo/lib/connect-mongo.js:161
            throw new Error('Error setting TTL index on collection : ' + s
                  ^
Error: Error setting TTL index on collection : sessions
at /home/dan/dev/audio-wave/node_modules/connect-mongo/lib/connect-mongo.js:161:23
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1404:28
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1542:30
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:159:22
at commandHandler (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:678:48)
at Db._executeQueryCommand (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1802:12)
at Cursor.nextObject (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:729:13)
at Cursor.toArray (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/cursor.js:158:10)
at Cursor.toArray (/home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/scope.js:10:20)
at /home/dan/dev/audio-wave/node_modules/connect-mongo/node_modules/mongodb/lib/mongodb/db.js:1541:65

Here's the code that ties it together

var sessionStore = new MongoStore({ db: 'audio-drop' })
  , cookieParser = express.cookieParser('waytoblue')
  , SessionSockets = require('session.socket.io')
  , sockets = new SessionSockets(io, sessionStore, cookieParser);

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.logger('dev'));
app.use(cookieParser);
app.use(express.session({
  store: sessionStore
}));

According to db.version() from the Mongo shell, I'm running 2.4.9 and I'm using version 0.4.0 of connect-mongo.

There seem to be a number of people who've hit this issue, but it seems that most of them resolved to being credential issues, my local mongo is not secured with authentication, so this can't be the problem. Any ideas?

回答1:

As I said in your comment, essentially Express is receiving connections before the session store is fully connected. The solution is to wait for the connection to occur before allowing your application to start listening.

You can avoid this problem by using a callback on MongoStore creation, or passing in an already active connection.

Example using connect-mongo's Callback

var sessionStore = new MongoStore({ url: 'someConnectionUrl', db: 'audio-drop' }, function(e) {

  var cookieParser = express.cookieParser('waytoblue');
  app.use(cookieParser);

  app.use(express.session({
    store: sessionStore
  }));

  app.listen();
});

Simple Mongoose Example

var mongoose = require('mongoose');

mongoose.connect('localhost', function(e) {
  // If error connecting
  if(e) throw e;

  var sessionStore = new MongoStore({ mongoose_connection: mongoose.connection }),
      cookieParser = express.cookieParser('waytoblue');

  app.use(cookieParser);

  app.use(express.session({
    store: sessionStore
  }));

  app.listen();
});


回答2:

Upgrade to connect-mongo version 0.8.0 which worked for me.



回答3:

angular fullstack example

It´s just to encapsulate all the other stuff inside the mongoose.connect callback function

See my server/app.js

/**
 * Main application file
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
var mongoose = require('mongoose');
var config = require('./config/environment');

// Connect to database
mongoose.connect(config.mongo.uri, config.mongo.options , function(e){


// Populate DB with sample data
  if(config.seedDB) { require('./config/seed'); }

// Setup server
  var app = express();
  var server = require('http').createServer(app);
  var socketio = require('socket.io')(server, {
    serveClient: (config.env === 'production') ? false : true,
    path: '/socket.io-client'
  });
  require('./config/socketio')(socketio);
  require('./config/express')(app);
  require('./routes')(app);

// Start server
  server.listen(config.port, config.ip, function () {
    console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
  });

// Expose app
  exports = module.exports = app;

});

Hope it helps!!