Skip to content

Commit f74e676

Browse files
committed
improve performance of denormalize thesaurus entities use case
1 parent 973a556 commit f74e676

File tree

5 files changed

+59
-32
lines changed

5 files changed

+59
-32
lines changed

app/api/core/application/DenormalizeThesaurusEntities.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { AbstractUseCase } from '../libs/UseCase';
44
import { PropertyAssignmentCreatorServiceStrategy } from './propertyAssignmentCreatorService/PropertyAssignmentCreatorServiceStrategy';
55

66
type Input = {
7+
thesaurusId: string;
78
sharedIds: string[];
89
};
910

@@ -26,14 +27,14 @@ class DenormalizeThesaurusEntitiesUseCase extends AbstractUseCase<Input, Output,
2627

2728
const [withRelationships, withoutRelationships] = ArrayUtils.splitInTwo(
2829
entities,
29-
entity => entity.getPropertyAssignmentsByType(['relationship']).length > 0
30+
entity => entity.getRelationshipAssignmentsInheritingFromSelect().length > 0
3031
);
3132

3233
await this.transactionManager.run(async () => {
3334
await ArrayUtils.sequentialFor(withoutRelationships, async entity => {
3435
const propertyAssignments =
3536
await this.deps.propertyAssignmentCreatorServiceStrategy.bulkCreate(
36-
entity.getPropertyAssignmentsByType(['select', 'multiselect', 'relationship']),
37+
entity.getSelectAssignmentsByThesaurusId(input.thesaurusId),
3738
entity.template
3839
);
3940

@@ -45,10 +46,12 @@ class DenormalizeThesaurusEntitiesUseCase extends AbstractUseCase<Input, Output,
4546
await ArrayUtils.sequentialFor(withRelationships, async entity => {
4647
const propertyAssignments =
4748
await this.deps.propertyAssignmentCreatorServiceStrategy.bulkCreate(
48-
entity.getPropertyAssignmentsByType(['select', 'multiselect', 'relationship']),
49+
[
50+
...entity.getRelationshipAssignmentsInheritingFromSelect(),
51+
...entity.getSelectAssignmentsByThesaurusId(input.thesaurusId),
52+
],
4953
entity.template
5054
);
51-
5255
entity.setPropertyAssignmentsInAllLanguages(propertyAssignments);
5356
});
5457

app/api/core/application/specs/DenormalizeThesaurusEntities.spec.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ describe('DenormalizeThesaurusEntities', () => {
2626
const { sut } = createSut();
2727

2828
await sut.execute({
29+
thesaurusId: factory.id('countries').toString(),
2930
sharedIds: ['entity_1', 'entity_2', 'entity_3', 'entity_4', 'entity_5'],
3031
});
3132

@@ -104,16 +105,16 @@ describe('DenormalizeThesaurusEntities', () => {
104105
language: 'en',
105106
sharedId: 'entity_4',
106107
metadata: {
107-
select: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
108-
multiselect: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
108+
select: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA V1' }],
109+
multiselect: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA V1' }],
109110
},
110111
},
111112
{
112113
language: 'es',
113114
sharedId: 'entity_4',
114115
metadata: {
115-
select: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
116-
multiselect: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
116+
select: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA ES V1' }],
117+
multiselect: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA ES V1' }],
117118
},
118119
},
119120
{
@@ -133,7 +134,9 @@ describe('DenormalizeThesaurusEntities', () => {
133134
{
134135
value: 'entity_4',
135136
label: 'entity_4',
136-
inheritedValue: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
137+
inheritedValue: [
138+
{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA V1' },
139+
],
137140
},
138141
],
139142
},
@@ -155,7 +158,9 @@ describe('DenormalizeThesaurusEntities', () => {
155158
{
156159
value: 'entity_4',
157160
label: 'entity_4',
158-
inheritedValue: [{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA' }],
161+
inheritedValue: [
162+
{ value: factory.id('thesaurus_2_usa').toString(), label: 'USA ES V1' },
163+
],
159164
},
160165
],
161166
},

app/api/core/application/specs/DenormalizeThesaurusEntitiesFixtures.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ export const fixtures: DBFixture = {
3131
factory.template('template_2', [
3232
factory.inherit('relationship_1', 'template_1', 'select', {
3333
relationType: factory.id('rel1').toHexString(),
34+
inherit: {
35+
type: 'select',
36+
property: factory.id('select').toString(),
37+
},
3438
}),
3539
factory.property('select', 'select', {
3640
content: factory.id('countries').toHexString(),
@@ -49,6 +53,10 @@ export const fixtures: DBFixture = {
4953
factory.template('template_4', [
5054
factory.inherit('relationship_to_t1', 'template_1', 'multiselect', {
5155
relationType: factory.id('rel2').toHexString(),
56+
inherit: {
57+
type: 'multiselect',
58+
property: factory.id('multiselect').toString(),
59+
},
5260
}),
5361
factory.inherit('relationship_to_t3', 'template_3', 'select', {
5462
relationType: factory.id('rel3').toHexString(),

app/api/core/domain/entity/Entity.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
PropertyAssignment,
99
PropertyValue,
1010
RelationshipEntry,
11+
SelectionEntry,
1112
TextPropertyValue,
1213
} from 'api/core/domain/template/PropertyValue';
1314
import {
@@ -18,7 +19,7 @@ import { AccessGrant, EntityPermission } from './EntityPermission';
1819
import { PermissionType } from './PermissionType';
1920
import { AccessLevel } from './AccessLevel';
2021
import { EntityTranslationDoesNotExistError } from './errors';
21-
import { PropertyType } from '../template/PropertyType';
22+
import { AbstractSelectProperty } from '../template/select/AbstractSelectProperty';
2223

2324
type CreateInput = {
2425
languages: LanguageISO6391[];
@@ -130,29 +131,35 @@ class Entity {
130131
return this.translationsList.map(([_language, translation]) => translation.metadata[name]);
131132
}
132133

133-
/**
134-
* Retrieves property assignments filtered by property type(s) for a specific language.
135-
*
136-
* @param type - Array of property types to filter by (e.g., ['text', 'numeric', 'relationship'])
137-
* @param targetLanguage - Optional language code (ISO 639-1). If not provided, defaults to the first available language
138-
* @returns Array of property assignments matching the specified type(s) in the target language
139-
*
140-
* @example
141-
* ```typescript
142-
* // Get all text and numeric properties in English
143-
* const textProps = entity.getPropertyAssignmentsByType(['text', 'numeric'], 'en');
144-
*
145-
* // Get relationship properties in default language
146-
* const relationships = entity.getPropertyAssignmentsByType(['relationship']);
147-
* ```
148-
*/
149-
getPropertyAssignmentsByType(
150-
type: PropertyType[],
134+
getRelationshipAssignmentsInheritingFromSelect(
135+
targetLanguage?: LanguageISO6391
136+
): PropertyAssignment<SelectionEntry>[] {
137+
const language = targetLanguage || this.languages[0];
138+
139+
const selectProperties = this.template.properties.filter(
140+
p =>
141+
p instanceof V1RelationshipProperty &&
142+
['select', 'multiselect'].includes(p.inherit?.type || '')
143+
);
144+
145+
return selectProperties.map(property =>
146+
this.getTranslation(language).getValue<SelectionEntry>(property.name)
147+
);
148+
}
149+
150+
getSelectAssignmentsByThesaurusId(
151+
thesaurusId: string,
151152
targetLanguage?: LanguageISO6391
152-
): PropertyAssignment[] {
153+
): PropertyAssignment<SelectionEntry>[] {
153154
const language = targetLanguage || this.languages[0];
154155

155-
return this.getTranslation(language).getByType(type);
156+
const selectProperties = this.template.properties.filter(
157+
p => p instanceof AbstractSelectProperty && p.content === thesaurusId
158+
);
159+
160+
return selectProperties.map(property =>
161+
this.getTranslation(language).getValue<SelectionEntry>(property.name)
162+
);
156163
}
157164

158165
addGrantForCreator(creatorId: string) {

app/api/core/infrastructure/jobs/DenormalizeThesaurusEntitiesChunkHandler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { DenormalizeThesaurusEntitiesUseCaseFactory } from '../factories/DenormalizeThesaurusEntitiesUseCaseFactory';
77

88
type Params = {
9+
thesaurusId: string;
910
sharedIds: string[];
1011
} & UserAwareDispatchableParams;
1112

@@ -21,7 +22,10 @@ class DenormalizeThesaurusEntitiesChunkHandler extends UserAwareDispatchable<Par
2122
protected async handle(_heartbeat: HeartbeatCallback, _jobInfo: JobInfo) {
2223
const useCase = this.deps.DenormalizeThesaurusEntitiesUseCaseFactory.default();
2324

24-
await useCase.execute({ sharedIds: this.params.sharedIds });
25+
await useCase.execute({
26+
sharedIds: this.params.sharedIds,
27+
thesaurusId: this.params.thesaurusId,
28+
});
2529
}
2630
}
2731

0 commit comments

Comments
 (0)