Skip to content

No indexes created when connected to a replica set with readPreference specified #11976

Closed
@CLaszlo

Description

@CLaszlo

Prerequisites

  • I have written a descriptive issue title
    I have searched existing issues to ensure the bug has not already been reported

Mongoose version

6.2.4

Node.js version

14.16.0

MongoDB server version

5.0.9

Description

In mongoose 6.2.4, indexes defined on schema paths are not created automatically when readPreference is set on the ConnectOptions.
The problem was noticed during the upgrade from mongoose 5.10.19 to 6.2.4. New databases created after the upgrade have been missing indexes.

Potentially related to #11711 and #10631

Setting {autoIndex: true} as a schema option seems to be a workaround for now.

Steps to Reproduce

  1. Start a replicaSet (potentially update the script below with the node ports)
  2. Run the code below with no args
  3. Run the code below with '--no-read-pref'

The snippet sets up two databases with the same schema. The schema defines two fields, one with a unique index.
When running with no args, the assert should fail, as only the _id index is created.
When running with '--no-read-pref' the indexes are created

const assert = require('assert');
const mongoose = require('mongoose');

const rsNodes = 'localhost:30001,localhost:30002,localhost:30003';
const mainDbName = 'mainDb';
const withoutReadPref = process.argv.includes('--no-read-pref');

const testSchema = new mongoose.Schema({
  field1: { type: String },
  field2: { type: String, unique: true }
});

function getDbConnectionOptions() {
  const dbOpts = {
    readPreference: 'primaryPreferred',
    replicaSet: 'rs'
  };

  if (withoutReadPref) {
    delete dbOpts.readPreference;
  }

  return dbOpts;
}

function getConnectionString(dbName) {
  return `mongodb://${rsNodes}/${dbName ? dbName : mainDbName}`;
}

async function registerModels(dbConn) {
  const model = dbConn.model('TestSchema', testSchema);

  if (!withoutReadPref) {
    // When read preference is specified, the collection does not get created automatically.
    await model.createCollection();
  }
}

async function getDbConnection(dbName) {
  const connectionOptions = getDbConnectionOptions();
  const connectionString = getConnectionString(dbName);

  let dbConn = mongoose.createConnection();

  await dbConn.openUri(connectionString, connectionOptions);
  await registerModels(dbConn);

  return dbConn;
}

async function init() {
  const mainDb = await getDbConnection();
  const mainDbTestSchema = mainDb.model('TestSchema');
  await new Promise((resolve) => setTimeout(resolve, 15000));
  const mainDbIndexes = await mainDbTestSchema.listIndexes();

  console.log(mainDbIndexes);
  assert.strictEqual(mainDbIndexes.length, 2);

  const tenantOneDb = await getDbConnection('tenantOne');
  const tenantOneDbTestSchema = tenantOneDb.model('TestSchema');
  await new Promise((resolve) => setTimeout(resolve, 15000));
  const tenantOneIndexes = await tenantOneDbTestSchema.listIndexes();

  console.log(tenantOneIndexes);
  assert.strictEqual(tenantOneIndexes.length, 2);
}

init();

Expected Behavior

The indexes should be created as the documentation states that autoIndex is true by default.

Activity

changed the title [-]No indexes created when connecting to a replica set with readPreference specified[/-] [+]No indexes created when connected to a replica set with readPreference specified[/+] on Jun 22, 2022
added this to the 6.4.2 milestone on Jun 25, 2022
emrsin

emrsin commented on Dec 27, 2022

@emrsin

This bug still happens if the readPreference is different of primary and primaryPreferred.
The only way that I found to solve this issue temporaly was using the sugestion shared by the @CLaszlo where I set autoIndex as true in the schema options.

vkarpov15

vkarpov15 commented on Dec 29, 2022

@vkarpov15
Collaborator

@emrsin can you please clarify the issue you're seeing?

emrsin

emrsin commented on Jan 5, 2023

@emrsin

@vkarpov15 if I set readPreference=secondaryPreferred in the connection string in a database with replica set configuration the collection's index do not create automatically.

vkarpov15

vkarpov15 commented on Jan 11, 2023

@vkarpov15
Collaborator

@emrsin that's expected behavior. MongoDB server doesn't allow any writes on secondaries, so trying to send a createIndex to a secondary would fail.

privateOmega

privateOmega commented on Jan 27, 2023

@privateOmega

@CLaszlo @emrsin Try syncing indexes await mongoose.syncIndexes(); once connection is established

danopia

danopia commented on Jul 28, 2023

@danopia

MongoDB server doesn't allow any writes on secondaries, so trying to send a createIndex to a secondary would fail.

Is this still true? According to the MongoDB ticket NODE-2784, this error was a bug in MongoDB driver 3.6.0 which was fixed in 3.6.3. I see that mongoose is using MongoDB driver 5.7.0 nowadays.

My read is that readPreference should not interfere with write operations like createIndex(); clearly Mongoose is also connected to primary MongoDB nodes if it is able to update documents.

Indeed, as said above, autoIndex: true seems to work fine with readPreference=secondaryPreferred.

vkarpov15

vkarpov15 commented on Aug 1, 2023

@vkarpov15
Collaborator

@danopia that's fair, it looks like you can use createIndex() with readPreference=secondaryPreferred, assuming that you are connected to the primary. Sending createIndex() to a secondary will still fail, but it looks like the MongoDB driver ignores readPreference=secondaryPreferred for createIndex() now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @danopia@vkarpov15@CLaszlo@privateOmega@emrsin

      Issue actions

        No indexes created when connected to a replica set with readPreference specified · Issue #11976 · Automattic/mongoose