🕵️ refactor: Optimize Message Search Performance (#9818)

* 🕵️ feat: Enhance Index Sync and MeiliSearch filtering for User Field

- Implemented `ensureFilterableAttributes` function to configure MeiliSearch indexes for messages and conversations to filter by user.
- Updated sync logic to trigger a full re-sync if the user field is missing or index settings are modified.
- Adjusted search queries in Conversation and Message models to include user filtering.
- Ensured 'user' field is marked as filterable in MongoDB schema for both messages and conversations.

This update improves data integrity and search capabilities by ensuring user-related data is properly indexed and retrievable.

* fix: message processing in Search component to use linear list and not tree

* feat: Implement user filtering in MeiliSearch for shared links

* refactor: Optimize message search retrieval by batching database calls

* chore: Update MeiliSearch parameters type to use SearchParams for improved type safety
This commit is contained in:
Danny Avila 2025-09-24 16:27:34 -04:00 committed by GitHub
parent f9aebeba92
commit 57f8b333bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 263 additions and 31 deletions

View file

@ -1,6 +1,6 @@
import _ from 'lodash';
import { MeiliSearch } from 'meilisearch';
import type { SearchResponse, Index } from 'meilisearch';
import type { SearchResponse, SearchParams, Index } from 'meilisearch';
import type {
CallbackWithoutResultAndOptionalError,
FilterQuery,
@ -75,7 +75,7 @@ export interface SchemaWithMeiliMethods extends Model<DocumentWithMeiliIndex> {
setMeiliIndexSettings(settings: Record<string, unknown>): Promise<unknown>;
meiliSearch(
q: string,
params?: Record<string, unknown>,
params?: SearchParams,
populate?: boolean,
): Promise<SearchResponse<MeiliIndexable, Record<string, unknown>>>;
}
@ -386,7 +386,7 @@ const createMeiliMongooseModel = ({
static async meiliSearch(
this: SchemaWithMeiliMethods,
q: string,
params: Record<string, unknown>,
params: SearchParams,
populate: boolean,
): Promise<SearchResponse<MeiliIndexable, Record<string, unknown>>> {
const data = await index.search(q, params);
@ -644,6 +644,16 @@ export default function mongoMeili(schema: Schema, options: MongoMeiliOptions):
logger.error(`[mongoMeili] Error checking index ${indexName}:`, error);
}
}
// Configure index settings to make 'user' field filterable
try {
await index.updateSettings({
filterableAttributes: ['user'],
});
logger.debug(`[mongoMeili] Updated index ${indexName} settings to make 'user' filterable`);
} catch (settingsError) {
logger.error(`[mongoMeili] Error updating index settings for ${indexName}:`, settingsError);
}
})();
// Collect attributes from the schema that should be indexed
@ -654,6 +664,13 @@ export default function mongoMeili(schema: Schema, options: MongoMeiliOptions):
}, []),
];
// CRITICAL: Always include 'user' field for proper filtering
// This ensures existing deployments can filter by user after migration
if (schema.obj.user && !attributesToIndex.includes('user')) {
attributesToIndex.push('user');
logger.debug(`[mongoMeili] Added 'user' field to ${indexName} index attributes`);
}
schema.loadClass(createMeiliMongooseModel({ index, attributesToIndex, syncOptions }));
// Register Mongoose hooks