2024-06-27 01:11:39 +02:00
|
|
|
import { getLogger } from "@logtape/logtape";
|
2024-04-07 06:16:54 +02:00
|
|
|
import { config } from "config-manager";
|
2024-04-13 14:24:57 +02:00
|
|
|
import { count } from "drizzle-orm";
|
2024-04-07 07:30:49 +02:00
|
|
|
import { Meilisearch } from "meilisearch";
|
2024-05-29 02:59:49 +02:00
|
|
|
import { db } from "~/drizzle/db";
|
|
|
|
|
import { Notes, Users } from "~/drizzle/schema";
|
|
|
|
|
import type { User } from "~/packages/database-interface/user";
|
2023-12-03 05:11:30 +01:00
|
|
|
|
|
|
|
|
export const meilisearch = new Meilisearch({
|
2024-04-07 07:30:49 +02:00
|
|
|
host: `${config.meilisearch.host}:${config.meilisearch.port}`,
|
|
|
|
|
apiKey: config.meilisearch.api_key,
|
2023-12-03 05:11:30 +01:00
|
|
|
});
|
|
|
|
|
|
2024-06-27 01:11:39 +02:00
|
|
|
export const connectMeili = async () => {
|
|
|
|
|
const logger = getLogger("meilisearch");
|
2024-06-13 04:26:43 +02:00
|
|
|
if (!config.meilisearch.enabled) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-07 07:30:49 +02:00
|
|
|
|
|
|
|
|
if (await meilisearch.isHealthy()) {
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Accounts)
|
|
|
|
|
.updateSortableAttributes(["createdAt"]);
|
|
|
|
|
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Accounts)
|
|
|
|
|
.updateSearchableAttributes(["username", "displayName", "note"]);
|
|
|
|
|
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Statuses)
|
|
|
|
|
.updateSortableAttributes(["createdAt"]);
|
|
|
|
|
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Statuses)
|
|
|
|
|
.updateSearchableAttributes(["content"]);
|
|
|
|
|
|
2024-06-27 01:11:39 +02:00
|
|
|
logger.info`Connected to Meilisearch`;
|
2024-04-07 07:30:49 +02:00
|
|
|
} else {
|
2024-06-27 01:11:39 +02:00
|
|
|
logger.fatal`Error while connecting to Meilisearch`;
|
2024-06-14 11:44:46 +02:00
|
|
|
// Hang until Ctrl+C is pressed
|
|
|
|
|
await Bun.sleep(Number.POSITIVE_INFINITY);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
2023-12-03 05:11:30 +01:00
|
|
|
};
|
|
|
|
|
|
2023-12-03 05:40:10 +01:00
|
|
|
export enum MeiliIndexType {
|
2024-04-07 07:30:49 +02:00
|
|
|
Accounts = "accounts",
|
|
|
|
|
Statuses = "statuses",
|
2023-12-03 05:11:30 +01:00
|
|
|
}
|
|
|
|
|
|
2023-12-03 05:45:01 +01:00
|
|
|
export const addUserToMeilisearch = async (user: User) => {
|
2024-06-13 04:26:43 +02:00
|
|
|
if (!config.meilisearch.enabled) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-07 07:30:49 +02:00
|
|
|
|
|
|
|
|
await meilisearch.index(MeiliIndexType.Accounts).addDocuments([
|
|
|
|
|
{
|
|
|
|
|
id: user.id,
|
2024-06-13 02:45:07 +02:00
|
|
|
username: user.data.username,
|
|
|
|
|
displayName: user.data.displayName,
|
|
|
|
|
note: user.data.note,
|
|
|
|
|
createdAt: user.data.createdAt,
|
2024-04-07 07:30:49 +02:00
|
|
|
},
|
|
|
|
|
]);
|
2023-12-03 05:45:01 +01:00
|
|
|
};
|
|
|
|
|
|
2023-12-03 05:11:30 +01:00
|
|
|
export const getNthDatabaseAccountBatch = (
|
2024-04-07 07:30:49 +02:00
|
|
|
n: number,
|
|
|
|
|
batchSize = 1000,
|
2023-12-03 05:40:10 +01:00
|
|
|
): Promise<Record<string, string | Date>[]> => {
|
2024-04-17 08:36:01 +02:00
|
|
|
return db.query.Users.findMany({
|
2024-04-13 14:24:57 +02:00
|
|
|
offset: n * batchSize,
|
|
|
|
|
limit: batchSize,
|
|
|
|
|
columns: {
|
2024-04-07 07:30:49 +02:00
|
|
|
id: true,
|
|
|
|
|
username: true,
|
|
|
|
|
displayName: true,
|
|
|
|
|
note: true,
|
|
|
|
|
createdAt: true,
|
|
|
|
|
},
|
2024-04-13 14:24:57 +02:00
|
|
|
orderBy: (user, { asc }) => asc(user.createdAt),
|
2024-04-07 07:30:49 +02:00
|
|
|
});
|
2023-12-03 05:11:30 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getNthDatabaseStatusBatch = (
|
2024-04-07 07:30:49 +02:00
|
|
|
n: number,
|
|
|
|
|
batchSize = 1000,
|
2023-12-03 05:40:10 +01:00
|
|
|
): Promise<Record<string, string | Date>[]> => {
|
2024-04-17 08:36:01 +02:00
|
|
|
return db.query.Notes.findMany({
|
2024-04-13 14:24:57 +02:00
|
|
|
offset: n * batchSize,
|
|
|
|
|
limit: batchSize,
|
|
|
|
|
columns: {
|
2024-04-07 07:30:49 +02:00
|
|
|
id: true,
|
|
|
|
|
content: true,
|
|
|
|
|
createdAt: true,
|
|
|
|
|
},
|
2024-04-13 14:24:57 +02:00
|
|
|
orderBy: (status, { asc }) => asc(status.createdAt),
|
2024-04-07 07:30:49 +02:00
|
|
|
});
|
2023-12-03 05:11:30 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const rebuildSearchIndexes = async (
|
2024-04-07 07:30:49 +02:00
|
|
|
indexes: MeiliIndexType[],
|
|
|
|
|
batchSize = 100,
|
2023-12-03 05:11:30 +01:00
|
|
|
) => {
|
2024-04-07 07:30:49 +02:00
|
|
|
if (indexes.includes(MeiliIndexType.Accounts)) {
|
2024-04-13 14:24:57 +02:00
|
|
|
const accountCount = (
|
|
|
|
|
await db
|
|
|
|
|
.select({
|
|
|
|
|
count: count(),
|
|
|
|
|
})
|
2024-04-17 08:36:01 +02:00
|
|
|
.from(Users)
|
2024-04-13 14:24:57 +02:00
|
|
|
)[0].count;
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
for (let i = 0; i < accountCount / batchSize; i++) {
|
|
|
|
|
const accounts = await getNthDatabaseAccountBatch(i, batchSize);
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-06-13 04:26:43 +02:00
|
|
|
/* const _progress = Math.round(
|
|
|
|
|
(i / (accountCount / batchSize)) * 100,
|
|
|
|
|
);
|
|
|
|
|
*/
|
2024-04-07 07:30:49 +02:00
|
|
|
// Sync with Meilisearch
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Accounts)
|
|
|
|
|
.addDocuments(accounts);
|
|
|
|
|
}
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-06-13 04:26:43 +02:00
|
|
|
/* const _meiliAccountCount = (
|
2024-04-07 07:30:49 +02:00
|
|
|
await meilisearch.index(MeiliIndexType.Accounts).getStats()
|
2024-06-13 04:26:43 +02:00
|
|
|
).numberOfDocuments; */
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
if (indexes.includes(MeiliIndexType.Statuses)) {
|
2024-04-13 14:24:57 +02:00
|
|
|
const statusCount = (
|
|
|
|
|
await db
|
|
|
|
|
.select({
|
|
|
|
|
count: count(),
|
|
|
|
|
})
|
2024-04-17 08:36:01 +02:00
|
|
|
.from(Notes)
|
2024-04-13 14:24:57 +02:00
|
|
|
)[0].count;
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
for (let i = 0; i < statusCount / batchSize; i++) {
|
|
|
|
|
const statuses = await getNthDatabaseStatusBatch(i, batchSize);
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-06-13 04:26:43 +02:00
|
|
|
/* const _progress = Math.round((i / (statusCount / batchSize)) * 100); */
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
// Sync with Meilisearch
|
|
|
|
|
await meilisearch
|
|
|
|
|
.index(MeiliIndexType.Statuses)
|
|
|
|
|
.addDocuments(statuses);
|
|
|
|
|
}
|
2023-12-03 05:11:30 +01:00
|
|
|
|
2024-06-13 04:26:43 +02:00
|
|
|
/* const _meiliStatusCount = (
|
2024-04-07 07:30:49 +02:00
|
|
|
await meilisearch.index(MeiliIndexType.Statuses).getStats()
|
2024-06-13 04:26:43 +02:00
|
|
|
).numberOfDocuments; */
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
2023-12-03 05:11:30 +01:00
|
|
|
};
|