[next] MongoDB Indexes (#2142)

* feat: added mongo indexing support

* fix: fixed typescript issue

* chore: better types

* fix: revert debug stuff

* fix: addressed ts error

* feat: added config option to disable auto-indexing

* chore: reordered imports

* refactor: cleaned up some filepaths
This commit is contained in:
Wyatt Johnson
2019-02-06 17:53:34 +00:00
committed by GitHub
parent 7e8ef2189d
commit 9b0e6ed53b
26 changed files with 397 additions and 126 deletions
+36 -5
View File
@@ -4,11 +4,14 @@ import uuid from "uuid";
import { Omit, Sub } from "talk-common/types";
import { GQLUSER_ROLE } from "talk-server/graph/tenant/schema/__generated__/types";
import { FilterQuery } from "talk-server/models/query";
import {
createIndexFactory,
FilterQuery,
} from "talk-server/models/helpers/query";
import { TenantResource } from "talk-server/models/tenant";
function collection(db: Db) {
return db.collection<Readonly<User>>("users");
function collection(mongo: Db) {
return mongo.collection<Readonly<User>>("users");
}
export interface LocalProfile {
@@ -66,6 +69,34 @@ export interface User extends TenantResource {
createdAt: Date;
}
export async function createUserIndexes(mongo: Db) {
const createIndex = createIndexFactory(collection(mongo));
// UNIQUE { id }
await createIndex({ tenantID: 1, id: 1 }, { unique: true });
// UNIQUE - PARTIAL { lowercaseUsername }
await createIndex(
{ tenantID: 1, lowercaseUsername: 1 },
{
unique: true,
partialFilterExpression: { lowercaseUsername: { $exists: true } },
}
);
// UNIQUE - PARTIAL { email }
await createIndex(
{ tenantID: 1, email: 1 },
{ unique: true, partialFilterExpression: { email: { $exists: true } } }
);
// UNIQUE { profiles.type, profiles.id }
await createIndex(
{ tenantID: 1, "profiles.type": 1, "profiles.id": 1 },
{ unique: true }
);
}
function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, 10);
}
@@ -171,7 +202,7 @@ const createUpsertUserFilter = (user: Readonly<User>) => {
};
export async function retrieveUser(db: Db, tenantID: string, id: string) {
return collection(db).findOne({ id, tenantID });
return collection(db).findOne({ tenantID, id });
}
export async function retrieveManyUsers(
@@ -194,7 +225,7 @@ export async function retrieveManyUsers(
export async function retrieveUserWithProfile(
db: Db,
tenantID: string,
profile: Partial<Profile>
profile: Partial<Pick<Profile, "id" | "type">>
) {
return collection(db).findOne({
tenantID,