Adjusted mongo indexes to support index scanning

This commit is contained in:
Wyatt Johnson
2017-12-04 09:05:40 -07:00
parent cbf3e4734d
commit 674ab19d06
8 changed files with 109 additions and 25 deletions
+4
View File
@@ -23,6 +23,10 @@ const CONFIG = {
APOLLO_ENGINE_KEY: process.env.APOLLO_ENGINE_KEY || null,
ENABLE_TRACING: Boolean(process.env.APOLLO_ENGINE_KEY),
// When TRUE, it ensures that database indexes created in core will not add
// indexes.
CREATE_MONGO_INDEXES: process.env.DISABLE_CREATE_MONGO_INDEXES !== 'TRUE',
//------------------------------------------------------------------------------
// JWT based configuration
//------------------------------------------------------------------------------
+3
View File
@@ -40,6 +40,9 @@ enum USER_ROLES {
# a staff of the site
STAFF
# a user without administrative roles.
COMMENTER
}
# Token is a personal access token associated with a given user.
+50 -5
View File
@@ -108,6 +108,21 @@ CommentSchema.index({
background: false
});
CommentSchema.index({
'status': 1,
'created_at': 1,
}, {
background: true,
});
CommentSchema.index({
'status': 1,
'created_at': 1,
'asset_id': 1,
}, {
background: true,
});
// Add an index that is optimized for sorting based on the action count data.
CommentSchema.index({
'created_at': 1,
@@ -116,7 +131,40 @@ CommentSchema.index({
background: true,
});
// TODO: Evaluate adding indexes for each reaction as well.
CommentSchema.index({
'created_at': 1,
'action_counts.flag': 1,
'status': 1,
}, {
background: true,
});
// Add an index that is optimized for finding flagged comments.
CommentSchema.index({
'asset_id': 1,
'created_at': 1,
'action_counts.flag': 1,
}, {
background: true,
});
// Add an index for the reply sort.
CommentSchema.index({
'asset_id': 1,
'created_at': -1,
'reply_count': -1,
}, {
background: true,
});
// Optimize for tag searches/counts.
CommentSchema.index({
'asset_id': 1,
'tags.tag.name': 1,
'status': 1,
}, {
background: true,
});
// Add an index that is optimized for sorting based on the created_at timestamp
// but also good at locating comments that have a specific asset id.
@@ -136,7 +184,4 @@ CommentSchema.virtual('visible').get(function() {
return ['ACCEPTED', 'NONE'].includes(this.status);
});
// Comment model.
const Comment = mongoose.model('Comment', CommentSchema);
module.exports = Comment;
module.exports = mongoose.model('Comment', CommentSchema);
+8
View File
@@ -220,6 +220,14 @@ UserSchema.index({
background: false
});
UserSchema.index({
'lowercaseUsername': 1,
'profiles.id': 1,
'created_at': -1,
}, {
background: true,
});
// This query is executed often, to count the number of flagged accounts with
// usernames.
UserSchema.index({
@@ -1,10 +1,24 @@
const {SEARCH_OTHER_USERS} = require('../../../perms/constants');
const errors = require('../../../errors');
const pluralize = require('pluralize');
const sc = require('snake-case');
const CommentModel = require('../../../models/comment');
const {CREATE_MONGO_INDEXES} = require('../../../config');
function getReactionConfig(reaction) {
reaction = reaction.toLowerCase();
if (CREATE_MONGO_INDEXES) {
// Create the index on the comment model based on the reaction config.
CommentModel.collection.createIndex({
created_at: 1,
[`action_counts.${sc(reaction)}`]: 1
}, {
background: true,
});
}
const reactionPlural = pluralize(reaction);
const Reaction = reaction.charAt(0).toUpperCase() + reaction.slice(1);
const REACTION = reaction.toUpperCase();
@@ -112,6 +126,14 @@ function getReactionConfig(reaction) {
return {
typeDefs,
schemas: ({CommentSchema}) => {
CommentSchema.index({
'created_at': 1,
[`action_counts.${sc(reaction)}`]: 1,
}, {
background: true,
});
},
context: {
Sort: () => ({
Comments: {
+5 -1
View File
@@ -5,7 +5,8 @@ const queryDebugger = require('debug')('talk:db:query');
const {
MONGO_URL,
WEBPACK
WEBPACK,
CREATE_MONGO_INDEXES,
} = require('../config');
// Loading the formatter from Mongoose:
@@ -56,6 +57,9 @@ if (WEBPACK) {
mongoose
.connect(MONGO_URL, {
useMongoClient: true,
config: {
autoIndex: CREATE_MONGO_INDEXES,
},
})
.then(() => {
debug('connection established');
+12 -10
View File
@@ -701,7 +701,10 @@ class UsersService {
return UserModel.find({});
}
value = escapeRegExp(value);
value = escapeRegExp(value).toLowerCase();
// Compile the prefix search regex.
const $regex = new RegExp(`^${value}`);
return UserModel.find({
$or: [
@@ -709,8 +712,8 @@ class UsersService {
// Search by a prefix match on the username.
{
'lowercaseUsername': {
$regex: new RegExp(value.toLowerCase())
}
$regex,
},
},
// Search by a prefix match on the email address.
@@ -718,14 +721,13 @@ class UsersService {
'profiles': {
$elemMatch: {
id: {
$regex: new RegExp(value),
$options: 'i'
$regex,
},
provider: 'local'
}
}
}
]
provider: 'local',
},
},
},
],
});
}
+5 -9
View File
@@ -186,18 +186,13 @@ describe('services.UsersService', () => {
it('should match the search terms', async () => {
const tests = [
{
search: 'monster',
results: 1,
id: mockUsers[1].id,
},
{
search: 'Stamp',
results: 1,
id: mockUsers[0].id,
},
{
search: 'sockmonster@gmail.com',
search: 'sockmonster',
results: 1,
id: mockUsers[1].id,
},
@@ -207,9 +202,10 @@ describe('services.UsersService', () => {
id: mockUsers[2].id,
},
{
search: 'gmail.com',
results: 3
}
search: 'marvel',
results: 1,
id: mockUsers[2].id,
},
];
for (const test of tests) {