Skip to content

Commit

Permalink
SERVICES-2371: simplify implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
dragos-rebegea committed Oct 27, 2024
1 parent 3ce1b36 commit 3620bab
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 81 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/cache/src/decorators/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './no.cache';
export * from './scrollable';
7 changes: 0 additions & 7 deletions packages/cache/src/decorators/scrollable.ts

This file was deleted.

43 changes: 21 additions & 22 deletions packages/cache/src/interceptors/scroll.interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Constants, ContextTracker, DecoratorUtils } from "@multiversx/sdk-nestjs-common";
import { Constants, ContextTracker, DecoratorUtils, ScrollableOptions, ScrollableCreateOptions, ScrollableAfterOptions } from "@multiversx/sdk-nestjs-common";
import { BadRequestException, CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common";
import { Observable, catchError, tap, throwError } from "rxjs";
import { randomUUID } from "crypto";
import { ScrollableOptions } from "../decorators";
import { CacheService } from "../cache";

@Injectable()
Expand Down Expand Up @@ -45,19 +44,19 @@ export class ScrollInterceptor implements NestInterceptor {

// create uuid and store
ContextTracker.assign({
scrollSettings: {
scrollCollection: scrollCollection,
scrollCreate: true,
},
scrollSettings: new ScrollableCreateOptions({
collection: scrollCollection,
create: true,
}),
});
} else if (guidRegex.test(scrollCreate)) {
scrollId = scrollCreate;

ContextTracker.assign({
scrollSettings: {
scrollCollection: scrollCollection,
scrollCreate: true,
},
scrollSettings: new ScrollableCreateOptions({
collection: scrollCollection,
create: true,
}),
});
} else {
throw new Error('Invalid scrollCreate value');
Expand All @@ -78,13 +77,13 @@ export class ScrollInterceptor implements NestInterceptor {
}

if (scrollInfo) {
ContextTracker.assign({
scrollSettings: {
scrollCollection: scrollCollection,
scrollAfter: scrollInfo.lastSort,
ContextTracker.assign(
new ScrollableAfterOptions({
collection: scrollCollection,
after: scrollInfo.lastSort,
ids: scrollInfo.lastIds,
},
});
})
);
}
} else {
throw new Error('Invalid scrollAfter value');
Expand All @@ -105,12 +104,12 @@ export class ScrollInterceptor implements NestInterceptor {
}

if (scrollInfo) {
ContextTracker.assign({
scrollSettings: {
scrollCollection: scrollCollection,
scrollAt: scrollInfo.firstSort,
},
});
ContextTracker.assign(
new ScrollableAfterOptions({
collection: scrollCollection,
after: scrollInfo.firstSort,
})
);
}
} else {
throw new Error('Invalid scrollAt value');
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './utils/url.utils';
export * from './utils/origin.logger';
export * from './utils/record.utils';
export * from './utils/round.utils';
export * from './utils/scrollable.utils';
export * from './utils/string.utils';
export * from './utils/swagger.utils';
export * from './utils/token.utils';
Expand Down
26 changes: 26 additions & 0 deletions packages/common/src/utils/scrollable.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export class ScrollableOptions {
collection: string = '';

constructor(init?: Partial<ScrollableOptions>) {
Object.assign(this, init);
}
}

export class ScrollableCreateOptions extends ScrollableOptions {
create: boolean = false;

constructor(init?: Partial<ScrollableCreateOptions>) {
super(init);
Object.assign(this, init);
}
}

export class ScrollableAfterOptions extends ScrollableOptions {
after: any;
ids: any[] = [];

constructor(init?: Partial<ScrollableAfterOptions>) {
super(init);
Object.assign(this, init);
}
}
69 changes: 25 additions & 44 deletions packages/elastic/src/elastic.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ApiService } from "@multiversx/sdk-nestjs-http";
import { MetricsService, ElasticMetricType, PerformanceProfiler } from "@multiversx/sdk-nestjs-monitoring";
import { ElasticQuery } from "./entities/elastic.query";
import { ElasticModuleOptions } from "./entities/elastic.module.options";
import { ContextTracker } from "@multiversx/sdk-nestjs-common";
import { ContextTracker, ScrollableAfterOptions } from "@multiversx/sdk-nestjs-common";

@Injectable()
export class ElasticService {
Expand Down Expand Up @@ -62,15 +62,12 @@ export class ElasticService {
private async getListResult(url: string, collection: string, elasticQuery: ElasticQuery) {
const scrollSettings = ContextTracker.get()?.scrollSettings;

const elasticQueryJson: any = elasticQuery.toJson();
if (scrollSettings && scrollSettings.scrollCollection === collection) {
if (scrollSettings && scrollSettings.collection === collection) {
let documents: any[] = [];

if (scrollSettings.scrollAfter) {
documents = await this.getScrollAfterResult(url, elasticQuery, scrollSettings.scrollAfter, scrollSettings.ids, elasticQuery.pagination?.size ?? 25);
} else if (scrollSettings.scrollAt) {
documents = await this.getScrollAtResult(url, elasticQuery, scrollSettings.scrollAt);
} else if (scrollSettings.scrollCreate) {
if (scrollSettings.after) {
documents = await this.getScrollAfterResult(url, elasticQuery, scrollSettings);
} else if (scrollSettings.create) {
documents = await this.getScrollCreateResult(url, elasticQuery);
} else {
throw new Error('Invalid scroll settings');
Expand All @@ -81,6 +78,7 @@ export class ElasticService {
return documents;
}

const elasticQueryJson: any = elasticQuery.toJson();
const result = await this.post(url, elasticQueryJson);
return result.data.hits.hits;
}
Expand Down Expand Up @@ -111,51 +109,34 @@ export class ElasticService {
});
}

private async getScrollAtResult(url: string, elasticQuery: ElasticQuery, scrollAt: any) {
const elasticQueryJson: any = elasticQuery.toJson();
elasticQueryJson.search_after = scrollAt;

const result = await this.post(url, elasticQueryJson);
return result.data.hits.hits;
}

private async getScrollAfterResult(url: string, elasticQuery: ElasticQuery, scrollAfter: any, ids: string[], size: number) {
const MAX_SIZE = 10000;

private async getScrollAfterResult(url: string, elasticQuery: ElasticQuery, scrollSettings: ScrollableAfterOptions) {
const elasticQueryJson: any = elasticQuery.toJson();

elasticQueryJson.search_after = scrollAfter;
elasticQueryJson.size += ids.length;

let remainingSize = 0;
if (elasticQueryJson.size > MAX_SIZE) {
remainingSize = elasticQueryJson.size - MAX_SIZE;
elasticQueryJson.size = MAX_SIZE;
}
elasticQueryJson.search_after = scrollSettings.after;
this.excludeIds(elasticQueryJson, scrollSettings.ids);

const queryResult = await this.post(url, elasticQueryJson);
const allDocuments = this.excludeIds(queryResult.data.hits.hits, ids, elasticQuery.pagination?.size);

let result = allDocuments;

if (remainingSize && allDocuments.length > 0) {
ids = this.getLastIds(allDocuments);
const lastDocumentSort = allDocuments[allDocuments.length - 1].sort;

elasticQueryJson.size = remainingSize + ids.length;
elasticQueryJson.search_after = lastDocumentSort;
return queryResult.data.hits.hits;
}

const remainingResult = await this.post(url, elasticQueryJson);
const remainingDocuments = this.excludeIds(remainingResult.data.hits.hits, ids, remainingSize);
private excludeIds(elasticQueryJson: any, ids: any[]) {
if (!elasticQueryJson.query) {
elasticQueryJson.query = {};
}

result = allDocuments.concat(remainingDocuments);
if (!elasticQueryJson.query.bool) {
elasticQueryJson.query.bool = {};
}

return result.slice(0, size);
}
if (!elasticQueryJson.query.bool.must_not) {
elasticQueryJson.query.bool.must_not = [];
}

private excludeIds(documents: any[], ids: string[], maxSize: number | undefined) {
return documents.filter((document: any) => !ids.includes(document._id)).slice(0, maxSize ?? 25);
elasticQueryJson.query.bool.must_not.push({
terms: {
_id: ids,
},
});
}

async getList(collection: string, key: string, elasticQuery: ElasticQuery, overrideUrl?: string): Promise<any[]> {
Expand Down

0 comments on commit 3620bab

Please sign in to comment.