matrix-search

A small nodejs script which indexes a whole matrix account into meilisearch and has a pdf rendering UI
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-search.git
Log | Files | Refs | README | LICENSE

indexer.ts (2283B)


      1 import { Hits, MeiliSearch } from 'meilisearch';
      2 import Config from './config.js';
      3 
      4 const config = new Config();
      5 
      6 /* This is the indexer. It is a wrapper around orama.
      7  *
      8  * It makes sure that the database is persisted on inserts and updates.
      9  * It also makes sure that the database is loaded on startup.
     10  * It also ensures the correct search is used.
     11  * 
     12 */
     13 export default class Indexer {
     14     private readonly client = new MeiliSearch({
     15         host: config.meiliSearchHost,
     16         apiKey: config.meiliSearchKey
     17     });
     18     private readonly textIndex = this.client.index('text');
     19 
     20     constructor() {
     21     }
     22 
     23     // TODO: Properly type the data
     24     public async insert(data: Record<string, any>) {
     25         return await this.textIndex.addDocuments([data], { primaryKey: 'id' });
     26     }
     27 
     28     public async search(query: string, room_id?: string, sender?: string, limit?: number) {
     29         await this.textIndex.updateSearchableAttributes(['content.body', "sender", "content.m.mentions.user_id", "room_name"]);
     30         await this.textIndex.updateFilterableAttributes([
     31             'id',
     32             'sender',
     33             'room_id',
     34             'origin_server_ts'
     35         ])
     36 
     37         let results: Hits<Record<string, any>> = [];
     38         let page = 1;
     39 
     40         let filter = "";
     41         if (room_id) {
     42             filter += `room_id = "${room_id}"`;
     43         }
     44         if (sender) {
     45             if (filter != "") {
     46                 filter += " AND ";
     47             }
     48             filter += `sender = "${sender}"`;
     49         }
     50         let filters;
     51         if (filter != "") {
     52             filters = [filter]
     53         }
     54 
     55         // Keep searching until we got everything
     56         let response = await this.textIndex.search(query, { page: page, filter: filters });
     57         results = results.concat(response.hits);
     58         while (page < response.totalPages) {
     59             response = await this.textIndex.search(query, { page: page, filter: filters });
     60             results = results.concat(response.hits);
     61             page++;
     62         }
     63 
     64         if (limit) {
     65             results = results.slice(0, limit);
     66         }
     67 
     68         return { hits: results, estimatedTotalHits: results.length };
     69     }
     70 
     71     public async delete(event_id: string) {
     72         return await this.textIndex.deleteDocument(event_id);
     73     }
     74 }