facilmap/server/src/database/search.ts

39 wiersze
1.3 KiB
TypeScript

import type { FindOnMapResult, PadId } from "facilmap-types";
import { type ModelStatic, Op, and, col, fn, where } from "sequelize";
import Database from "./database.js";
import type { LineModel } from "./line.js";
import type { MarkerModel } from "./marker.js";
import { compareTwoStrings } from "string-similarity";
export default class DatabaseSearch {
_db: Database;
constructor(database: Database) {
this._db = database;
}
async search(padId: PadId, searchText: string): Promise<Array<FindOnMapResult>> {
const objects = (await Promise.all([ "Marker", "Line" ].map(async (kind) => {
const model = this._db._conn.model(kind) as ModelStatic<MarkerModel | LineModel>;
const objs = await model.findAll<MarkerModel | LineModel>({
where: and(
{ padId },
where(fn("lower", col(`${kind}.name`)), {[Op.like]: `%${searchText.toLowerCase()}%`})
),
attributes: [ "id", "name", "typeId" ].concat(kind == "Marker" ? [ "pos", "lat", "lon", "icon" ] : [ "top", "left", "bottom", "right" ])
});
return objs.map((obj) => ({
...obj.toJSON(),
kind: kind.toLowerCase() as any,
similarity: compareTwoStrings(searchText, obj.name ?? '')
}));
}))).flat();
objects.sort((a, b) => (b.similarity - a.similarity));
return objects;
}
}