mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
feat: ✨ Add CLI command to rebuild index
This commit is contained in:
parent
19c15f7e96
commit
93b8609411
|
|
@ -184,16 +184,18 @@ export class SonicSearchManager {
|
||||||
* Rebuild search indexes
|
* Rebuild search indexes
|
||||||
* @param indexes Indexes to rebuild
|
* @param indexes Indexes to rebuild
|
||||||
* @param batchSize Size of each batch
|
* @param batchSize Size of each batch
|
||||||
|
* @param progressCallback Callback for progress updates
|
||||||
*/
|
*/
|
||||||
async rebuildSearchIndexes(
|
async rebuildSearchIndexes(
|
||||||
indexes: SonicIndexType[],
|
indexes: SonicIndexType[],
|
||||||
batchSize = 100,
|
batchSize = 100,
|
||||||
|
progressCallback?: (progress: number) => void,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const index of indexes) {
|
for (const index of indexes) {
|
||||||
if (index === SonicIndexType.Accounts) {
|
if (index === SonicIndexType.Accounts) {
|
||||||
await this.rebuildAccountsIndex(batchSize);
|
await this.rebuildAccountsIndex(batchSize, progressCallback);
|
||||||
} else if (index === SonicIndexType.Statuses) {
|
} else if (index === SonicIndexType.Statuses) {
|
||||||
await this.rebuildStatusesIndex(batchSize);
|
await this.rebuildStatusesIndex(batchSize, progressCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -201,8 +203,12 @@ export class SonicSearchManager {
|
||||||
/**
|
/**
|
||||||
* Rebuild accounts index
|
* Rebuild accounts index
|
||||||
* @param batchSize Size of each batch
|
* @param batchSize Size of each batch
|
||||||
|
* @param progressCallback Callback for progress updates
|
||||||
*/
|
*/
|
||||||
private async rebuildAccountsIndex(batchSize: number): Promise<void> {
|
private async rebuildAccountsIndex(
|
||||||
|
batchSize: number,
|
||||||
|
progressCallback?: (progress: number) => void,
|
||||||
|
): Promise<void> {
|
||||||
const accountCount = await User.getCount();
|
const accountCount = await User.getCount();
|
||||||
const batchCount = Math.ceil(accountCount / batchSize);
|
const batchCount = Math.ceil(accountCount / batchSize);
|
||||||
|
|
||||||
|
|
@ -221,15 +227,19 @@ export class SonicSearchManager {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.logger.info`Indexed accounts batch ${i + 1}/${batchCount}`;
|
progressCallback?.((i + 1) / batchCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild statuses index
|
* Rebuild statuses index
|
||||||
* @param batchSize Size of each batch
|
* @param batchSize Size of each batch
|
||||||
|
* @param progressCallback Callback for progress updates
|
||||||
*/
|
*/
|
||||||
private async rebuildStatusesIndex(batchSize: number): Promise<void> {
|
private async rebuildStatusesIndex(
|
||||||
|
batchSize: number,
|
||||||
|
progressCallback?: (progress: number) => void,
|
||||||
|
): Promise<void> {
|
||||||
const statusCount = await Note.getCount();
|
const statusCount = await Note.getCount();
|
||||||
const batchCount = Math.ceil(statusCount / batchSize);
|
const batchCount = Math.ceil(statusCount / batchSize);
|
||||||
|
|
||||||
|
|
@ -245,7 +255,7 @@ export class SonicSearchManager {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
this.logger.info`Indexed statuses batch ${i + 1}/${batchCount}`;
|
progressCallback?.((i + 1) / batchCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
68
cli/commands/index/rebuild.ts
Normal file
68
cli/commands/index/rebuild.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { Args, Flags } from "@oclif/core";
|
||||||
|
import ora from "ora";
|
||||||
|
import { SonicIndexType, searchManager } from "~/classes/search/search-manager";
|
||||||
|
import { BaseCommand } from "~/cli/base";
|
||||||
|
import { config } from "~/packages/config-manager";
|
||||||
|
|
||||||
|
export default class IndexRebuild extends BaseCommand<typeof IndexRebuild> {
|
||||||
|
static override args = {
|
||||||
|
type: Args.string({
|
||||||
|
description: "Index category to rebuild",
|
||||||
|
options: ["accounts", "statuses"],
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
static override description = "Rebuild search indexes";
|
||||||
|
|
||||||
|
static override examples = ["<%= config.bin %> <%= command.id %>"];
|
||||||
|
|
||||||
|
static override flags = {
|
||||||
|
"batch-size": Flags.integer({
|
||||||
|
char: "b",
|
||||||
|
description: "Number of items to process in each batch",
|
||||||
|
default: 100,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
public async run(): Promise<void> {
|
||||||
|
const { flags, args } = await this.parse(IndexRebuild);
|
||||||
|
|
||||||
|
if (!config.sonic.enabled) {
|
||||||
|
this.error("Sonic search is disabled");
|
||||||
|
this.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await searchManager.connect();
|
||||||
|
|
||||||
|
const spinner = ora("Rebuilding search indexes").start();
|
||||||
|
|
||||||
|
switch (args.type) {
|
||||||
|
case "accounts":
|
||||||
|
await searchManager.rebuildSearchIndexes(
|
||||||
|
[SonicIndexType.Accounts],
|
||||||
|
flags["batch-size"],
|
||||||
|
(progress) => {
|
||||||
|
spinner.text = `Rebuilding search indexes (${(progress * 100).toFixed(2)}%)`;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "statuses":
|
||||||
|
await searchManager.rebuildSearchIndexes(
|
||||||
|
[SonicIndexType.Statuses],
|
||||||
|
flags["batch-size"],
|
||||||
|
(progress) => {
|
||||||
|
spinner.text = `Rebuilding search indexes (${(progress * 100).toFixed(2)}%)`;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
this.error("Invalid index type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spinner.succeed("Search indexes rebuilt");
|
||||||
|
|
||||||
|
this.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { configureLoggers } from "@/loggers";
|
||||||
import { execute } from "@oclif/core";
|
import { execute } from "@oclif/core";
|
||||||
import EmojiAdd from "./commands/emoji/add";
|
import EmojiAdd from "./commands/emoji/add";
|
||||||
import EmojiDelete from "./commands/emoji/delete";
|
import EmojiDelete from "./commands/emoji/delete";
|
||||||
import EmojiImport from "./commands/emoji/import";
|
import EmojiImport from "./commands/emoji/import";
|
||||||
import EmojiList from "./commands/emoji/list";
|
import EmojiList from "./commands/emoji/list";
|
||||||
|
import IndexRebuild from "./commands/index/rebuild";
|
||||||
import Start from "./commands/start";
|
import Start from "./commands/start";
|
||||||
import UserCreate from "./commands/user/create";
|
import UserCreate from "./commands/user/create";
|
||||||
import UserDelete from "./commands/user/delete";
|
import UserDelete from "./commands/user/delete";
|
||||||
|
|
@ -10,6 +12,8 @@ import UserList from "./commands/user/list";
|
||||||
import UserRefetch from "./commands/user/refetch";
|
import UserRefetch from "./commands/user/refetch";
|
||||||
import UserReset from "./commands/user/reset";
|
import UserReset from "./commands/user/reset";
|
||||||
|
|
||||||
|
await configureLoggers();
|
||||||
|
|
||||||
// Use "explicit" oclif strategy to avoid issues with oclif's module resolver and bundling
|
// Use "explicit" oclif strategy to avoid issues with oclif's module resolver and bundling
|
||||||
export const commands = {
|
export const commands = {
|
||||||
"user:list": UserList,
|
"user:list": UserList,
|
||||||
|
|
@ -21,6 +25,7 @@ export const commands = {
|
||||||
"emoji:delete": EmojiDelete,
|
"emoji:delete": EmojiDelete,
|
||||||
"emoji:list": EmojiList,
|
"emoji:list": EmojiList,
|
||||||
"emoji:import": EmojiImport,
|
"emoji:import": EmojiImport,
|
||||||
|
"index:rebuild": IndexRebuild,
|
||||||
start: Start,
|
start: Start,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue