update search algorithm

This commit is contained in:
Youwen Wu 2024-02-13 13:37:58 -08:00
parent b621b51799
commit eb790fb6ac
3 changed files with 52 additions and 11 deletions

View file

@ -66,7 +66,7 @@ export interface DocumentManifest {
status: DocumentStatus status: DocumentStatus
reviewers?: reviewer[] reviewers?: reviewer[]
} }
export const documents: { [key: string]: Document } = { export const documents: Readonly<{ [key: string]: Document }> = {
'day-5-principles': { 'day-5-principles': {
manifest: { manifest: {
title: 'Day 5 Principles', title: 'Day 5 Principles',
@ -316,7 +316,7 @@ export interface Topic {
description: string description: string
wiki: string wiki: string
} }
export const topics: { [key: string]: Topic } = { export const topics: Readonly<{ [key: string]: Topic }> = {
frc: { frc: {
name: 'FIRST Robotics Competition', name: 'FIRST Robotics Competition',
description: description:
@ -386,7 +386,7 @@ export interface Author {
bio?: string bio?: string
website?: string website?: string
} }
export const authors: { [key: string]: Author } = { export const authors: Readonly<{ [key: string]: Author }> = {
shasan: { shasan: {
name: { name: {
first: 'Saim', first: 'Saim',
@ -533,7 +533,7 @@ export interface Affiliation {
description: string description: string
} }
export const affiliations: { [key: string]: Affiliation } = { export const affiliations: Readonly<{ [key: string]: Affiliation }> = {
'1280-mech': { '1280-mech': {
name: "Team 1280, the Ragin' C Biscuits, Mechanical Subteam", name: "Team 1280, the Ragin' C Biscuits, Mechanical Subteam",
short: '1280 Mech', short: '1280 Mech',
@ -689,7 +689,7 @@ export interface Nationality {
demonym: string demonym: string
flag: string flag: string
} }
export const nationalities: { [key: string]: Nationality } = { export const nationalities: Readonly<{ [key: string]: Nationality }> = {
pak: { pak: {
name: 'Pakistan', name: 'Pakistan',
demonym: 'Pakistani', demonym: 'Pakistani',

View file

@ -19,6 +19,15 @@ const SearchResult = ({
const { manifest, abstract, id } = result const { manifest, abstract, id } = result
const { title, authors, topics, dates, status, type } = manifest const { title, authors, topics, dates, status, type } = manifest
/*
this is not a recommended design pattern for creating a clickable object,
as it's terrible for accessibility. we should add accessibility tags to make it
recognizable as a clickable item.
the reason we aren't simply wrapping the search result in a <Link> tag is because
React does not support nested <a> tags and it overrides the links displayed inside.
this click handling logic simply checks to see if the element clicked is a nested link
and fires a redirect if not, to avoid overriding links in the children
*/
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => { const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
let target = event.target as HTMLElement let target = event.target as HTMLElement
while (target != null) { while (target != null) {

View file

@ -1,29 +1,61 @@
import { documents } from '@/app/db/data' import { documents, authors, affiliations, topics } from '@/app/db/data'
import MiniSearch from 'minisearch' import MiniSearch from 'minisearch'
import { CustomSearchResult } from './searchDocs' import { CustomSearchResult } from './searchDocs'
// converting the documents object into an array that can be index by minisearch
const docs = Object.entries(documents).map(([key, value]) => ({ const docs = Object.entries(documents).map(([key, value]) => ({
id: key, id: key,
keywords: value.manifest.keywords.join(' '), keywords: value.manifest.keywords.join(' '),
abstract: value.abstract, abstract: value.abstract,
topics: value.manifest.topics.join(' '), topics: value.manifest.topics
authors: value.manifest.authors.join(' '), .map((topicId) => topics[topicId])
.map((topic) => topic.name)
.join(' '),
authors: value.manifest.authors // pull out author data from the user id
.map((authorId) => authors[authorId])
.map(
(author) =>
`${author.name.first} ${author.name.last} ${author.name.nickname}`
)
.join(' '),
title: value.manifest.title, title: value.manifest.title,
manifest: value.manifest, manifest: value.manifest,
type: value.manifest.type, type: value.manifest.type,
affiliations: value.manifest.authors // pull the affiliation metadata from the author data
.map((authorId) => authors[authorId])
.map((author) => author.affiliation)
.map((affiliationId) =>
affiliationId
.map(
(af) =>
`${affiliations[af.split('@')[1]].name} ${affiliations[af.split('@')[1]].short}`
)
.join(' ')
)
.join(' '),
key: key,
})) }))
const miniSearch = new MiniSearch({ const miniSearch = new MiniSearch({
fields: ['abstract', 'keywords', 'topics', 'authors', 'title', 'type'], fields: [
'abstract',
'keywords',
'topics',
'authors',
'title',
'type',
'affiliations',
],
storeFields: ['key', 'abstract', 'manifest'], storeFields: ['key', 'abstract', 'manifest'],
searchOptions: { searchOptions: {
boost: { boost: {
title: 2, title: 3,
keywords: 2, keywords: 2,
topics: 1, topics: 1,
authors: 2, authors: 2,
abstract: 0.3,
}, },
fuzzy: 0.2, fuzzy: 2,
prefix: true, prefix: true,
}, },
}) })