From e5175194acb77d861759f519802d5a984e7dde51 Mon Sep 17 00:00:00 2001 From: Marie <51697796+ijreilly@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:24:54 +0200 Subject: [PATCH] Fix search on workspace member (#8066) Adding search vectors on workspaceMember and tasks --- .../constants/standard-field-ids.ts | 2 ++ .../standard-objects/task.workspace-entity.ts | 33 +++++++++++++++-- .../workspace-member.workspace-entity.ts | 35 +++++++++++++++++-- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index 2ab951392..ec2690693 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -350,6 +350,7 @@ export const TASK_STANDARD_FIELD_IDS = { assignee: '20202020-065a-4f42-a906-e20422c1753f', timelineActivities: '20202020-c778-4278-99ee-23a2837aee64', favorites: '20202020-4d1d-41ac-b13b-621631298d65', + searchVector: '20202020-4746-4e2f-870c-52b02c67c90d', }; export const TASK_TARGET_STANDARD_FIELD_IDS = { @@ -490,6 +491,7 @@ export const WORKSPACE_MEMBER_STANDARD_FIELD_IDS = { timeZone: '20202020-2d33-4c21-a86e-5943b050dd54', dateFormat: '20202020-af13-4e11-b1e7-b8cf5ea13dc0', timeFormat: '20202020-8acb-4cf8-a851-a6ed443c8d81', + searchVector: '20202020-46d0-4e7f-bc26-74c0edaeb619', }; export const CUSTOM_OBJECT_STANDARD_FIELD_IDS = { diff --git a/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts index 77f7b7272..1244a5606 100644 --- a/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts +++ b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts @@ -1,16 +1,19 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; +import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; import { ActorMetadata, FieldActorSource, } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceFieldIndex } from 'src/engine/twenty-orm/decorators/workspace-field-index.decorator'; import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; @@ -18,12 +21,24 @@ import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace- import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; import { TASK_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { + FieldTypeAndNameMetadata, + getTsVectorColumnExpressionFromFields, +} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util'; import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity'; import { TaskTargetWorkspaceEntity } from 'src/modules/task/standard-objects/task-target.workspace-entity'; import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity'; import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; +const TITLE_FIELD_NAME = 'title'; +const BODY_FIELD_NAME = 'body'; + +export const SEARCH_FIELDS_FOR_TASK: FieldTypeAndNameMetadata[] = [ + { name: TITLE_FIELD_NAME, type: FieldMetadataType.TEXT }, + { name: BODY_FIELD_NAME, type: FieldMetadataType.RICH_TEXT }, +]; + @WorkspaceEntity({ standardId: STANDARD_OBJECT_IDS.task, namePlural: 'tasks', @@ -53,7 +68,7 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity { description: 'Task title', icon: 'IconNotes', }) - title: string; + [TITLE_FIELD_NAME]: string; @WorkspaceField({ standardId: TASK_STANDARD_FIELD_IDS.body, @@ -63,7 +78,7 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity { icon: 'IconFilePencil', }) @WorkspaceIsNullable() - body: string | null; + [BODY_FIELD_NAME]: string | null; @WorkspaceField({ standardId: TASK_STANDARD_FIELD_IDS.dueAt, @@ -177,4 +192,18 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity { }) @WorkspaceIsSystem() favorites: Relation; + + @WorkspaceField({ + standardId: TASK_STANDARD_FIELD_IDS.searchVector, + type: FieldMetadataType.TS_VECTOR, + label: SEARCH_VECTOR_FIELD.label, + description: SEARCH_VECTOR_FIELD.description, + icon: 'IconUser', + generatedType: 'STORED', + asExpression: getTsVectorColumnExpressionFromFields(SEARCH_FIELDS_FOR_TASK), + }) + @WorkspaceIsNullable() + @WorkspaceIsSystem() + @WorkspaceFieldIndex({ indexType: IndexType.GIN }) + [SEARCH_VECTOR_FIELD.name]: any; } diff --git a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts index 83371beb3..44fe88feb 100644 --- a/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts +++ b/packages/twenty-server/src/modules/workspace-member/standard-objects/workspace-member.workspace-entity.ts @@ -3,14 +3,17 @@ import { registerEnumType } from '@nestjs/graphql'; import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; +import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; import { FullNameMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity'; import { RelationMetadataType, RelationOnDeleteAction, } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceFieldIndex } from 'src/engine/twenty-orm/decorators/workspace-field-index.decorator'; import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator'; import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator'; @@ -19,6 +22,10 @@ import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; import { WORKSPACE_MEMBER_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; +import { + FieldTypeAndNameMetadata, + getTsVectorColumnExpressionFromFields, +} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util'; import { ActivityWorkspaceEntity } from 'src/modules/activity/standard-objects/activity.workspace-entity'; import { CommentWorkspaceEntity } from 'src/modules/activity/standard-objects/comment.workspace-entity'; import { AttachmentWorkspaceEntity } from 'src/modules/attachment/standard-objects/attachment.workspace-entity'; @@ -57,6 +64,14 @@ registerEnumType(WorkspaceMemberDateFormatEnum, { 'Date format as Month first, Day first, Year first or system as default', }); +const NAME_FIELD_NAME = 'name'; +const USER_EMAIL_FIELD_NAME = 'userEmail'; + +export const SEARCH_FIELDS_FOR_WORKSPACE_MEMBER: FieldTypeAndNameMetadata[] = [ + { name: NAME_FIELD_NAME, type: FieldMetadataType.FULL_NAME }, + { name: USER_EMAIL_FIELD_NAME, type: FieldMetadataType.TEXT }, +]; + @WorkspaceEntity({ standardId: STANDARD_OBJECT_IDS.workspaceMember, namePlural: 'workspaceMembers', @@ -76,7 +91,7 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity { description: 'Workspace member name', icon: 'IconCircleUser', }) - name: FullNameMetadata; + [NAME_FIELD_NAME]: FullNameMetadata; @WorkspaceField({ standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.colorScheme, @@ -114,7 +129,7 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity { description: 'Related user email address', icon: 'IconMail', }) - userEmail: string; + [USER_EMAIL_FIELD_NAME]: string; @WorkspaceField({ standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.userId, @@ -374,4 +389,20 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity { defaultValue: `'${WorkspaceMemberTimeFormatEnum.SYSTEM}'`, }) timeFormat: string; + + @WorkspaceField({ + standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.searchVector, + type: FieldMetadataType.TS_VECTOR, + label: SEARCH_VECTOR_FIELD.label, + description: SEARCH_VECTOR_FIELD.description, + icon: 'IconUser', + generatedType: 'STORED', + asExpression: getTsVectorColumnExpressionFromFields( + SEARCH_FIELDS_FOR_WORKSPACE_MEMBER, + ), + }) + @WorkspaceIsNullable() + @WorkspaceIsSystem() + @WorkspaceFieldIndex({ indexType: IndexType.GIN }) + [SEARCH_VECTOR_FIELD.name]: any; }