I currently have a basic course search feature with a custom pipe filter, stackblitz here. It returns results based on whether there exists a match in the course title
, description
or keywords
, but it returns the courses in some arbitrary order. I'd like to modify the pipe to return more relevant results first, with the precedence being that the search query matched in 1. the title, 2. the description, 3. the keywords.
Some test case examples:
The query
"chinese"
currently returns"1 French"
before"1X Chinese"
because there's a match in the keywords to"chinese"
for"1 French"
.the query
"linear algebra"
returns54 Math
first before89A statistics
, even though the latter has a match in all 3 fields.
What would be the best way to go about implementing this? I'm currently looking at this response, which would mean I could try to define my own comparator with the following logic (in pseudocode)
orderByComparator(a:Course, b:Course):number{
if(searchRelevancy(a) < searchRelevancy(b)) return -1;
else if(searchRelevancy(a) > searchRelevancy(b)) return 1;
else return 0;
}
where searchRelevancy
could be a function that calculates the rank of each course based on the query
searchRelevancy(course: Course, query: string): number{
var rank: number;
if(course.course_title.toUpperCase().includes(query)) rank += 5;
if(course.description.toUpperCase().includes(query)) rank += 3;
if(course.keywords.toUpperCase().includes(query)) rank += 1;
return rank
}
and the view would include
<li *ngFor="let course of courses | courseFilter: searchText |
orderBy: ['title', 'description', ''keywords]">
However, I'm relatively new to Angular and the implementation details were beyond what I can currently follow. Is this the most straightforward approach? If I know I'm only filtering course objects, is it possible to modify the current course-filter pipe without defining a second orderBy pipe?
Any pointers would be appreciated!