Create indexes for most used fields

Create indexes for most used fields

Closes #995

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2022-02-12 01:12:12 +07:00
parent d13f4690b6
commit cfbefe9fef
No known key found for this signature in database
GPG Key ID: BD80F68D68D8F7F2
3 changed files with 59 additions and 21 deletions

View File

@ -13,44 +13,37 @@
// limitations under the License. // limitations under the License.
// //
import type { IntlString } from '@anticrm/platform' import {
import type {
Account, Account,
AnyAttribute, AnyAttribute, ArrOf, AttachedDoc,
AttachedDoc,
Class, Class,
ClassifierKind, ClassifierKind, Collection, Doc,
Doc, Domain, DOMAIN_MODEL, IndexKind, Interface, Mixin,
Domain,
Mixin,
Obj, Obj,
Ref, Ref, RefTo, Space,
Space,
Timestamp, Timestamp,
Type, Type, Version
Collection,
RefTo,
ArrOf,
Interface,
Version
} from '@anticrm/core' } from '@anticrm/core'
import { DOMAIN_MODEL } from '@anticrm/core' import { Index, Model, Prop, TypeRef, TypeString, TypeTimestamp } from '@anticrm/model'
import { Model, Prop, TypeRef, TypeString, TypeTimestamp } from '@anticrm/model' import type { IntlString } from '@anticrm/platform'
import core from './component' import core from './component'
// C O R E // C O R E
@Model(core.class.Obj, core.class.Obj) @Model(core.class.Obj, core.class.Obj)
export class TObj implements Obj { export class TObj implements Obj {
@Prop(TypeRef(core.class.Class), 'Class' as IntlString) @Prop(TypeRef(core.class.Class), 'Class' as IntlString)
@Index(IndexKind.Indexed)
_class!: Ref<Class<this>> _class!: Ref<Class<this>>
} }
@Model(core.class.Doc, core.class.Obj) @Model(core.class.Doc, core.class.Obj)
export class TDoc extends TObj implements Doc { export class TDoc extends TObj implements Doc {
@Prop(TypeRef(core.class.Doc), 'Id' as IntlString) @Prop(TypeRef(core.class.Doc), 'Id' as IntlString)
// @Index(IndexKind.Indexed) // - automatically indexed by default.
_id!: Ref<this> _id!: Ref<this>
@Prop(TypeRef(core.class.Space), 'Space' as IntlString) @Prop(TypeRef(core.class.Space), 'Space' as IntlString)
@Index(IndexKind.Indexed)
space!: Ref<Space> space!: Ref<Space>
@Prop(TypeTimestamp(), 'Modified' as IntlString) @Prop(TypeTimestamp(), 'Modified' as IntlString)
@ -63,9 +56,11 @@ export class TDoc extends TObj implements Doc {
@Model(core.class.AttachedDoc, core.class.Doc) @Model(core.class.AttachedDoc, core.class.Doc)
export class TAttachedDoc extends TDoc implements AttachedDoc { export class TAttachedDoc extends TDoc implements AttachedDoc {
@Prop(TypeRef(core.class.Doc), 'Attached to' as IntlString) @Prop(TypeRef(core.class.Doc), 'Attached to' as IntlString)
@Index(IndexKind.Indexed)
attachedTo!: Ref<Doc> attachedTo!: Ref<Doc>
@Prop(TypeRef(core.class.Class), 'Attached to class' as IntlString) @Prop(TypeRef(core.class.Class), 'Attached to class' as IntlString)
@Index(IndexKind.Indexed)
attachedToClass!: Ref<Class<Doc>> attachedToClass!: Ref<Class<Doc>>
@Prop(TypeString(), 'Collection' as IntlString) @Prop(TypeString(), 'Collection' as IntlString)

View File

@ -81,7 +81,8 @@ export interface Type<T extends PropertyType> extends UXObject {}
* @public * @public
*/ */
export enum IndexKind { export enum IndexKind {
FullText FullText,
Indexed
} }
/** /**

View File

@ -14,10 +14,10 @@
// //
import contact from '@anticrm/contact' import contact from '@anticrm/contact'
import core, { DOMAIN_TX, Tx } from '@anticrm/core' import core, { DOMAIN_TX, Tx, Client as CoreClient, Domain, IndexKind, DOMAIN_MODEL } from '@anticrm/core'
import builder, { createDeps, migrateOperations } from '@anticrm/model-all' import builder, { createDeps, migrateOperations } from '@anticrm/model-all'
import { Client } from 'minio' import { Client } from 'minio'
import { Document, MongoClient } from 'mongodb' import { Db, Document, MongoClient } from 'mongodb'
import { connect } from './connect' import { connect } from './connect'
import toolPlugin from './plugin' import toolPlugin from './plugin'
import { MigrateClientImpl } from './upgrade' import { MigrateClientImpl } from './upgrade'
@ -106,6 +106,9 @@ export async function initModel (transactorUrl: string, dbName: string): Promise
await connection.close() await connection.close()
} }
// Create update indexes
await createUpdateIndexes(connection, db)
console.log('create minio bucket') console.log('create minio bucket')
if (!(await minio.bucketExists(dbName))) { if (!(await minio.bucketExists(dbName))) {
await minio.makeBucket(dbName, 'k8s') await minio.makeBucket(dbName, 'k8s')
@ -154,6 +157,10 @@ export async function upgradeModel (
console.log('Apply upgrade operations') console.log('Apply upgrade operations')
const connection = await connect(transactorUrl, dbName, true) const connection = await connect(transactorUrl, dbName, true)
// Create update indexes
await createUpdateIndexes(connection, db)
for (const op of migrateOperations) { for (const op of migrateOperations) {
await op.upgrade(connection) await op.upgrade(connection)
} }
@ -163,3 +170,38 @@ export async function upgradeModel (
await client.close() await client.close()
} }
} }
async function createUpdateIndexes (connection: CoreClient, db: Db): Promise<void> {
const classes = await connection.findAll(core.class.Class, {})
const hierarchy = connection.getHierarchy()
const domains = new Map<Domain, Set<string>>()
// Find all domains and indexed fields inside
for (const c of classes) {
try {
const domain = hierarchy.getDomain(c._id)
if (domain === DOMAIN_MODEL) {
continue
}
const attrs = hierarchy.getAllAttributes(c._id)
const domainAttrs = domains.get(domain) ?? new Set<string>()
for (const a of attrs.values()) {
if (a.index !== undefined && a.index === IndexKind.Indexed) {
domainAttrs.add(a.name)
}
}
domains.set(domain, domainAttrs)
} catch (err: any) {
// Ignore, since we have clases without domain.
}
}
for (const [d, v] of domains.entries()) {
const collection = db.collection(d)
for (const vv of v.values()) {
console.log('creating index', d, vv)
await collection.createIndex(vv)
}
}
}