From 9800bc93c69d943b97b331a10ce329436fba9998 Mon Sep 17 00:00:00 2001 From: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> Date: Tue, 24 May 2022 16:19:31 +0600 Subject: [PATCH] 1846 fix (#1854) Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com> --- dev/tool/src/elastic.ts | 30 ++++++++++++++++++++++ server/core/src/fulltext.ts | 48 ++++++++++++++++------------------- server/elastic/src/adapter.ts | 2 +- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/dev/tool/src/elastic.ts b/dev/tool/src/elastic.ts index f9b757a2f2..b22e971632 100644 --- a/dev/tool/src/elastic.ts +++ b/dev/tool/src/elastic.ts @@ -211,9 +211,14 @@ async function restoreElastic (mongoUrl: string, dbName: string, minio: Client, const isCollectionCreateTx = (tx: Tx): boolean => tx._class === core.class.TxCollectionCUD && (tx as TxCollectionCUD).tx._class === core.class.TxCreateDoc + const isMixinTx = (tx: Tx): boolean => + tx._class === core.class.TxMixin || + (tx._class === core.class.TxCollectionCUD && + (tx as TxCollectionCUD).tx._class === core.class.TxMixin) const createTxes = data.filter((tx) => isCreateTx(tx)) const collectionTxes = data.filter((tx) => isCollectionCreateTx(tx)) + const mixinTxes = data.filter((tx) => isMixinTx(tx)) const removedDocument = new Set>() const startCreate = Date.now() @@ -287,6 +292,31 @@ async function restoreElastic (mongoUrl: string, dbName: string, minio: Client, ) console.log('replay elastic collection transactions done', Date.now() - startCollection) + const startMixin = Date.now() + console.log('replay elastic mixin transactions', mixinTxes.length) + await Promise.all( + mixinTxes.map(async (tx) => { + try { + let deleted = false + if (tx._class === core.class.TxMixin) { + deleted = removedDocument.has((tx as TxMixin).objectId) + } + if ( + tx._class === core.class.TxCollectionCUD && + (tx as TxCollectionCUD).tx._class === core.class.TxMixin + ) { + deleted = removedDocument.has((tx as TxCollectionCUD).tx.objectId) + } + if (!deleted) { + await tool.storage.tx(metricsCtx, tx) + } + } catch (err: any) { + console.error('failed to replay tx', tx, err.message) + } + }) + ) + console.log('replay elastic mixin transactions done', Date.now() - startMixin) + let apos = 0 if (await minio.bucketExists(dbName)) { const minioObjects = await listMinioObjects(minio, dbName) diff --git a/server/core/src/fulltext.ts b/server/core/src/fulltext.ts index 1ab039e700..91d8950fea 100644 --- a/server/core/src/fulltext.ts +++ b/server/core/src/fulltext.ts @@ -165,28 +165,7 @@ export class FullTextIndex implements WithFind { } } const resultIds = Array.from(getResultIds(ids, _id)) - if (options?.limit === undefined) { - return await this.getResult(ctx, _class, resultIds, mainQuery as DocumentQuery, options) - } else { - const result: T[] = [] - const size = options.limit - let start = 0 - while (true) { - const ids = resultIds.slice(start, start + size) - const res = await this.getResult(ctx, _class, ids, mainQuery as DocumentQuery, options) - result.push(...res) - if (result.length >= size || res.length < size) { - break - } - start += size - } - if (result.length >= size) { - const total = await this.getResult(ctx, _class, resultIds, mainQuery as DocumentQuery, { limit: 1 }) - - return toFindResult(result, total.total) - } - return toFindResult(result) - } + return await this.getResult(ctx, _class, resultIds, mainQuery as DocumentQuery, options) } private async getResult( @@ -200,14 +179,31 @@ export class FullTextIndex implements WithFind { for (let index = 0; index < ids.length; index++) { orderMap.set(ids[index], index) } + const { sort, ...otherOptions } = options ?? {} + if (options?.lookup !== undefined && options.limit !== undefined) { + const resIds = await this.dbStorage.findAll( + ctx, + _class, + { _id: { $in: ids }, ...mainQuery }, + { projection: { _id: 1 } } + ) + const total = resIds.total + resIds.sort((a, b) => (orderMap.get(a._id) ?? 0) - (orderMap.get(b._id) ?? 0)) + const targetIds = resIds.slice(0, options.limit).map((p) => p._id) - const result = await this.dbStorage.findAll(ctx, _class, { _id: { $in: ids }, ...mainQuery }, options) + const result = await this.dbStorage.findAll(ctx, _class, { _id: { $in: targetIds }, ...mainQuery }, otherOptions) + result.sort((a, b) => (orderMap.get(a._id) ?? 0) - (orderMap.get(b._id) ?? 0)) - const total = result.total + return toFindResult(result, total) + } else { + const result = await this.dbStorage.findAll(ctx, _class, { _id: { $in: ids }, ...mainQuery }, otherOptions) - result.sort((a, b) => (orderMap.get(a._id) ?? 0) - (orderMap.get(b._id) ?? 0)) + const total = result.total - return toFindResult(result, total) + result.sort((a, b) => (orderMap.get(a._id) ?? 0) - (orderMap.get(b._id) ?? 0)) + + return toFindResult(result, total) + } } private getFullTextAttributes (clazz: Ref>, parentDoc?: Doc): AnyAttribute[] { diff --git a/server/elastic/src/adapter.ts b/server/elastic/src/adapter.ts index 5822d243df..2663f14a10 100644 --- a/server/elastic/src/adapter.ts +++ b/server/elastic/src/adapter.ts @@ -47,7 +47,7 @@ class ElasticAdapter implements FullTextAdapter { { terms: { _class: _classes.map((c) => c.toLowerCase()), - boost: 10.0 + boost: 50.0 } } ],