How to specify index options with Meteor / Mongo Collections?

Was reading this meteor-mongodb optimization article (here How to optimize your Mongo database for Meteor.js) and wondering what is the best way to specify indexes for mongodb collections.

For example, can we specify indexes while inserting new documents, something like collection.insert({...}, {index: ...})

If not, what is the best practice to ensure best indexing / performance?

8 Likes

@KrishnaPG

Similarly, like at MySQL you can add indexes to speed up queries, and look at slow query logs. When using MongoDB, looking at slow query logs, you can then add indexes when starting Meteor app.

When using Meteor, if database is empty, Meteor creates all collections/tables to database.

This way you can also add indexes, for example at models/cards.js:

  Meteor.startup(() => {
    Cards._collection.createIndex({ modifiedAt: -1 });
    Cards._collection.createIndex({ boardId: 1, createdAt: -1 });
  });

Currently there are these indexes:

./find.sh createIndex

./models/cards.js:    Cards._collection.createIndex({ modifiedAt: -1 });
./models/cards.js:    Cards._collection.createIndex({ boardId: 1, createdAt: -1 });
./models/cards.js:    Cards._collection.createIndex({ parentId: 1 });
./models/invitationCodes.js:    InvitationCodes._collection.createIndex({ modifiedAt: -1 });
./models/team.js:    Team._collection.createIndex({ teamDisplayName: 1 });
./models/checklistItems.js:    ChecklistItems._collection.createIndex({ modifiedAt: -1 });
./models/checklistItems.js:    ChecklistItems._collection.createIndex({ checklistId: 1 });
./models/checklistItems.js:    ChecklistItems._collection.createIndex({ cardId: 1 });
./models/rules.js:    Rules._collection.createIndex({ modifiedAt: -1 });
./models/actions.js:    Actions._collection.createIndex({ modifiedAt: -1 });
./models/org.js:    // Org._collection.createIndex({ name: -1 });
./models/org.js:    Org._collection.createIndex({ orgDisplayName: 1 });
./models/activities.js:    Activities._collection.createIndex({ createdAt: -1 });
./models/activities.js:    Activities._collection.createIndex({ modifiedAt: -1 });
./models/activities.js:    Activities._collection.createIndex({ cardId: 1, createdAt: -1 });
./models/activities.js:    Activities._collection.createIndex({ boardId: 1, createdAt: -1 });
./models/activities.js:    Activities._collection.createIndex(
./models/activities.js:    Activities._collection.createIndex(
./models/activities.js:    Activities._collection.createIndex(
./models/users.js:      Lists._collection.createIndex(value);
./models/users.js:    Users._collection.createIndex({
./models/users.js:    Users._collection.createIndex(
./models/triggers.js:    Triggers._collection.createIndex({ modifiedAt: -1 });
./models/lists.js:    Lists._collection.createIndex({ modifiedAt: -1 });
./models/lists.js:    Lists._collection.createIndex({ boardId: 1 });
./models/lists.js:    Lists._collection.createIndex({ archivedAt: -1 });
./models/accountSettings.js:    AccountSettings._collection.createIndex({ modifiedAt: -1 });
./models/boards.js:    Boards._collection.createIndex({ modifiedAt: -1 });
./models/boards.js:    Boards._collection.createIndex(
./models/boards.js:    Boards._collection.createIndex({ 'members.userId': 1 });
./models/unsavedEdits.js:    UnsavedEditCollection._collection.createIndex({ modifiedAt: -1 });
./models/unsavedEdits.js:    UnsavedEditCollection._collection.createIndex({ userId: 1 });
./models/announcements.js:    Announcements._collection.createIndex({ modifiedAt: -1 });
./models/integrations.js:    Integrations._collection.createIndex({ modifiedAt: -1 });
./models/integrations.js:    Integrations._collection.createIndex({ boardId: 1 });
./models/cardCommentReactions.js:    CardCommentReactions._collection.createIndex({ cardCommentId: 1 }, { unique: true });
./models/customFields.js:    CustomFields._collection.createIndex({ modifiedAt: -1 });
./models/customFields.js:    CustomFields._collection.createIndex({ boardIds: 1 });
./models/checklists.js:    Checklists._collection.createIndex({ modifiedAt: -1 });
./models/checklists.js:    Checklists._collection.createIndex({ cardId: 1, createdAt: 1 });
./models/tableVisibilityModeSettings.js:    TableVisibilityModeSettings._collection.createIndex({ modifiedAt: -1 });
./models/swimlanes.js:    Swimlanes._collection.createIndex({ modifiedAt: -1 });
./models/swimlanes.js:    Swimlanes._collection.createIndex({ boardId: 1 });
./models/attachments.js:    Attachments.collection.createIndex({ 'meta.cardId': 1 });
./models/cardComments.js:    CardComments._collection.createIndex({ modifiedAt: -1 });
./models/cardComments.js:    CardComments._collection.createIndex({ cardId: 1, createdAt: -1 });
./models/orgUser.js:    OrgUser._collection.createIndex({ orgId: -1 });
./models/orgUser.js:    OrgUser._collection.createIndex({ orgId: -1, userId: -1 });
./models/settings.js:    Settings._collection.createIndex({ modifiedAt: -1 });
./models/translation.js:    Translation._collection.createIndex({ modifiedAt: -1 });
./packages/wekan-accounts-sandstorm/server.js:    Meteor.users.createIndex("services.sandstorm.id", {unique: 1, sparse: 1});

At WeKan, that is made with Meteor GitHub - wekan/wekan: The Open Source kanban (built with Meteor). Keep variable/table/field names camelCase. For translations, only add Pull Request changes to wekan/i18n/en.i18n.json , other translations are done at https://app.transifex.com/wekan/ only.

If needing migrations to new schema, when using SimplSchema, those changes are done at migration.js:

Although, making a lot of changes could slow down starting Meteor app, if there is a lot of data. In that case, you could just use data without migrations, because MongoDB allows adding additional fields, even when those fields will be saved only to newest data, and old data does not have those fields.