Use MS sorting rather than manual JS
This commit is contained in:
parent
c9c183fec0
commit
933a4d2aa2
@ -121,6 +121,19 @@ if (hasConfig) {
|
||||
),
|
||||
);
|
||||
|
||||
posts
|
||||
.updateRankingRules([
|
||||
"sort",
|
||||
"words",
|
||||
"typo",
|
||||
"proximity",
|
||||
"attribute",
|
||||
"exactness",
|
||||
])
|
||||
.catch((e) => {
|
||||
logger.error("Failed to set ranking rules, sorting won't work properly.");
|
||||
});
|
||||
|
||||
logger.info("Connected to MeiliSearch");
|
||||
}
|
||||
|
||||
@ -160,6 +173,7 @@ export default hasConfig
|
||||
limit: number,
|
||||
offset: number,
|
||||
userCtx: ILocalUser | null,
|
||||
overrideSort: string | null,
|
||||
) => {
|
||||
/// Advanced search syntax
|
||||
/// from:user => filter by user + optional domain
|
||||
@ -170,8 +184,10 @@ export default hasConfig
|
||||
/// "text" => get posts with exact text between quotes
|
||||
/// filter:following => show results only from users you follow
|
||||
/// filter:followers => show results only from followers
|
||||
/// order:desc/asc => order results ascending or descending
|
||||
|
||||
const constructedFilters: string[] = [];
|
||||
let sortRules: string[] = [];
|
||||
|
||||
const splitSearch = query.split(" ");
|
||||
|
||||
@ -278,6 +294,14 @@ export default hasConfig
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
} else if (term.startsWith("order:desc")) {
|
||||
sortRules.push("createdAt:desc");
|
||||
|
||||
return null;
|
||||
} else if (term.startsWith("order:asc")) {
|
||||
sortRules.push("createdAt:asc");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -286,14 +310,27 @@ export default hasConfig
|
||||
)
|
||||
).filter((term) => term !== null);
|
||||
|
||||
const sortRules = [];
|
||||
|
||||
// An empty search term with defined filters means we have a placeholder search => https://www.meilisearch.com/docs/reference/api/search#placeholder-search
|
||||
// These have to be ordered manually, otherwise the *oldest* posts are returned first, which we don't want
|
||||
if (filteredSearchTerms.length === 0 && constructedFilters.length > 0) {
|
||||
// If the user has defined a sort rule, don't mess with it
|
||||
if (
|
||||
filteredSearchTerms.length === 0 &&
|
||||
constructedFilters.length > 0 &&
|
||||
sortRules.length === 0
|
||||
) {
|
||||
sortRules.push("createdAt:desc");
|
||||
}
|
||||
|
||||
// More than one sorting rule doesn't make sense. We only keep the first one, otherwise weird stuff may happen.
|
||||
if (sortRules.length > 1) {
|
||||
sortRules = [sortRules[0]];
|
||||
}
|
||||
|
||||
// An override sort takes precedence, user sorting is ignored here
|
||||
if (overrideSort) {
|
||||
sortRules = [overrideSort];
|
||||
}
|
||||
|
||||
logger.info(`Searching for ${filteredSearchTerms.join(" ")}`);
|
||||
logger.info(`Limit: ${limit}`);
|
||||
logger.info(`Offset: ${offset}`);
|
||||
|
@ -191,11 +191,10 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||
chunkSize,
|
||||
start,
|
||||
me,
|
||||
sortByDate ? "createdAt:desc" : null,
|
||||
);
|
||||
const results: MeilisearchNote[] = searchRes.hits as MeilisearchNote[];
|
||||
|
||||
console.log(JSON.stringify(results));
|
||||
|
||||
start += chunkSize;
|
||||
|
||||
if (results.length === 0) {
|
||||
@ -226,13 +225,6 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||
});
|
||||
|
||||
extractedNotes.push(...res);
|
||||
console.log(extractedNotes);
|
||||
}
|
||||
|
||||
// Depending on the ordering requested, return the notes sorted by relevancy as
|
||||
// returned by Meilisearch or order chronologically
|
||||
if (sortByDate) {
|
||||
extractedNotes.sort((a, b) => b.createdAt - a.createdAt);
|
||||
}
|
||||
|
||||
// Fetch the notes from the database until we have enough to satisfy the limit
|
||||
@ -240,29 +232,18 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||
const found = [];
|
||||
const noteIDs = extractedNotes.map((note) => note.id);
|
||||
|
||||
// Index the ID => index number into a map, so we can sort efficiently later
|
||||
// Index the ID => index number into a map, so we can restore the array ordering efficiently later
|
||||
const idIndexMap = new Map(noteIDs.map((id, index) => [id, index]));
|
||||
|
||||
while (found.length < ps.limit && start < noteIDs.length) {
|
||||
const chunk = noteIDs.slice(start, start + chunkSize);
|
||||
|
||||
let query: FindManyOptions = sortByDate
|
||||
? {
|
||||
where: {
|
||||
id: In(chunk),
|
||||
},
|
||||
order: {
|
||||
id: "DESC",
|
||||
},
|
||||
}
|
||||
: {
|
||||
let query: FindManyOptions = {
|
||||
where: {
|
||||
id: In(chunk),
|
||||
},
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(query));
|
||||
|
||||
const notes: Note[] = await Notes.find(query);
|
||||
|
||||
// Re-order the note result according to the noteIDs array (cannot be undefined, we map this earlier)
|
||||
|
Loading…
Reference in New Issue
Block a user