Files
fluxer/fluxer_api/pkgs/elasticsearch_search/src/ElasticsearchIndexDefinitions.ts
T

243 lines
5.5 KiB
TypeScript

// SPDX-License-Identifier: AGPL-3.0-or-later
type ElasticsearchFieldType = 'text' | 'keyword' | 'boolean' | 'long' | 'integer' | 'date' | 'float';
export type FluxerSearchIndexName =
| 'messages'
| 'guilds'
| 'users'
| 'reports'
| 'audit_logs'
| 'guild_members'
| 'threads';
interface ElasticsearchFieldMapping {
type: ElasticsearchFieldType;
index?: boolean;
analyzer?: string;
search_analyzer?: string;
fields?: Record<string, ElasticsearchFieldMapping>;
}
interface ElasticsearchIndexSettings {
number_of_shards?: number;
number_of_replicas?: number;
analysis?: Record<string, unknown>;
}
export interface ElasticsearchIndexDefinition {
indexName: FluxerSearchIndexName;
mappings: {
properties: Record<string, ElasticsearchFieldMapping>;
};
settings?: ElasticsearchIndexSettings;
}
const GUILD_DISCOVERY_ANALYSIS: Record<string, unknown> = {
analyzer: {
discovery_folding: {
type: 'custom',
tokenizer: 'standard',
filter: ['lowercase', 'asciifolding'],
},
},
};
function discoveryText(): ElasticsearchFieldMapping {
return {
type: 'text',
analyzer: 'discovery_folding',
search_analyzer: 'discovery_folding',
fields: {keyword: {type: 'keyword'}},
};
}
function textWithKeyword(): ElasticsearchFieldMapping {
return {type: 'text', fields: {keyword: {type: 'keyword'}}};
}
function keyword(): ElasticsearchFieldMapping {
return {type: 'keyword'};
}
function bool(): ElasticsearchFieldMapping {
return {type: 'boolean'};
}
function long(): ElasticsearchFieldMapping {
return {type: 'long'};
}
function integer(): ElasticsearchFieldMapping {
return {type: 'integer'};
}
export const ELASTICSEARCH_INDEX_DEFINITIONS: Record<FluxerSearchIndexName, ElasticsearchIndexDefinition> = {
messages: {
indexName: 'messages',
mappings: {
properties: {
id: keyword(),
channelId: keyword(),
guildId: keyword(),
authorId: keyword(),
authorType: keyword(),
content: textWithKeyword(),
createdAt: long(),
editedAt: long(),
isPinned: bool(),
mentionedUserIds: keyword(),
mentionEveryone: bool(),
hasLink: bool(),
hasEmbed: bool(),
hasPoll: bool(),
hasFile: bool(),
hasVideo: bool(),
hasImage: bool(),
hasSound: bool(),
hasSticker: bool(),
hasForward: bool(),
embedTypes: keyword(),
embedProviders: keyword(),
embedContent: {type: 'text'},
linkHostnames: keyword(),
attachmentFilenames: keyword(),
attachmentExtensions: keyword(),
},
},
},
guilds: {
indexName: 'guilds',
settings: {analysis: GUILD_DISCOVERY_ANALYSIS},
mappings: {
properties: {
id: keyword(),
ownerId: keyword(),
name: discoveryText(),
vanityUrlCode: discoveryText(),
discoveryDescription: discoveryText(),
discoveryTags: discoveryText(),
discoveryPrimaryLanguage: keyword(),
iconHash: keyword(),
bannerHash: keyword(),
splashHash: keyword(),
features: keyword(),
verificationLevel: integer(),
mfaLevel: integer(),
nsfwLevel: integer(),
createdAt: long(),
memberCount: integer(),
discoveryCategory: integer(),
isDiscoverable: bool(),
},
},
},
users: {
indexName: 'users',
mappings: {
properties: {
id: keyword(),
username: textWithKeyword(),
email: textWithKeyword(),
discriminator: integer(),
isBot: bool(),
isSystem: bool(),
flags: keyword(),
premiumType: integer(),
emailVerified: bool(),
emailBounced: bool(),
acls: keyword(),
createdAt: long(),
lastActiveAt: long(),
tempBannedUntil: long(),
pendingDeletionAt: long(),
stripeSubscriptionId: keyword(),
stripeCustomerId: keyword(),
},
},
},
reports: {
indexName: 'reports',
mappings: {
properties: {
id: keyword(),
reporterId: keyword(),
reportedAt: long(),
status: integer(),
reportType: integer(),
category: textWithKeyword(),
reason: keyword(),
additionalInfo: textWithKeyword(),
reportedUserId: keyword(),
reportedWebhookId: keyword(),
reportedGuildId: keyword(),
reportedGuildName: textWithKeyword(),
reportedMessageId: keyword(),
reportedChannelId: keyword(),
reportedChannelName: textWithKeyword(),
guildContextId: keyword(),
resolvedAt: long(),
resolvedByAdminId: keyword(),
publicComment: keyword(),
createdAt: long(),
},
},
},
threads: {
indexName: 'threads',
mappings: {
properties: {
id: keyword(),
guildId: keyword(),
parentId: keyword(),
type: integer(),
name: textWithKeyword(),
ownerId: keyword(),
archived: bool(),
locked: bool(),
appliedTagIds: keyword(),
createdAt: long(),
idSequence: long(),
lastMessageAt: long(),
archivedAt: long(),
},
},
},
audit_logs: {
indexName: 'audit_logs',
mappings: {
properties: {
id: keyword(),
logId: keyword(),
adminUserId: keyword(),
targetType: textWithKeyword(),
targetId: textWithKeyword(),
action: textWithKeyword(),
auditLogReason: textWithKeyword(),
createdAt: long(),
},
},
},
guild_members: {
indexName: 'guild_members',
mappings: {
properties: {
id: keyword(),
guildId: keyword(),
userId: textWithKeyword(),
username: textWithKeyword(),
usernameSearch: textWithKeyword(),
discriminator: textWithKeyword(),
globalName: textWithKeyword(),
nickname: textWithKeyword(),
roleIds: keyword(),
joinedAt: long(),
joinSourceType: integer(),
sourceInviteCode: keyword(),
inviterId: keyword(),
userCreatedAt: long(),
isBot: bool(),
},
},
},
};