Skip to content

Commit

Permalink
Merge pull request #3 from twin-te/update-name-and-query
Browse files Browse the repository at this point in the history
講義名をandで検索、科目番号を前方一致
  • Loading branch information
SIY1121 authored Mar 21, 2022
2 parents c2fa19d + ba51c2e commit ac2ee4a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
4 changes: 2 additions & 2 deletions __tests__/usecase/searchCourse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ test('キーワード検索単体', async () => {
test('キーワード複数', async () => {
const res = await searchCourseUseCase({
year: 2020,
keywords: ['情報', 'スポーツ'],
keywords: ['情報', '人工知能'],
searchMode: SearchMode.Cover,
offset: 0,
limit: 30,
})
expect(res.length > 0).toBe(true)
expect(res.length <= 30).toBe(true)
res.forEach((c) =>
expect(c.name.includes('情報') || c.name.includes('スポーツ')).toBe(true)
expect(c.name.includes('情報') && c.name.includes('人工知能')).toBe(true)
)
})

Expand Down
39 changes: 32 additions & 7 deletions src/usecase/searchCourse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ type Input = {
offset: number
}

const escapeRegex = (str: string) =>
str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')

/**
* 指定されたキーワードをすべて含む文字列にヒットする正規表現を生成
* 肯定先読みを使って順不同andを実装
* 授業名等の検索で使用
*/
const searchNameRegexp = (names: string[]) =>
'^' +
names
.map(escapeRegex)
.map((n) => `(?=.*${n})`)
.join('')

/**
* 指定された科目番号に前方一致でヒットする正規表現を生成
*/
const searchCodeRegexp = (codes: string[]) =>
`^(${codes.map(escapeRegex).join('|')})`

export async function searchCourseUseCase({
year,
timetable,
Expand Down Expand Up @@ -74,7 +95,7 @@ export async function searchCourseUseCase({
join course_schedules as s on s.course_id=courses.id
where
courses.year = :year and
(courses.name ~* :keywords or courses.code ~* :keywords) AND
(courses.name ~* :names or courses.code ~* :codes) AND
(
${conditions
.map(
Expand Down Expand Up @@ -106,7 +127,7 @@ export async function searchCourseUseCase({
join course_schedules as s on s.course_id=courses.id
where
courses.year = :year and
(courses.name ~* :keywords or courses.code ~* :keywords) and (
(courses.name ~* :names or courses.code ~* :codes) and (
${conditions
.map(
({ periods }, i) => `(
Expand All @@ -128,7 +149,11 @@ export async function searchCourseUseCase({
)
`

const parameters: any = { keywords: keywords.join('|'), year }
const parameters: any = {
names: searchNameRegexp(keywords),
codes: searchCodeRegexp(keywords),
year,
}
conditions.forEach(({ module, day, periods }, i) => {
parameters[`m_${i}`] = module
parameters[`d_${i}`] = day
Expand Down Expand Up @@ -162,14 +187,14 @@ export async function searchCourseUseCase({
where: [
{
year,
name: Raw((alias) => `${alias} ~* :keywords`, {
keywords: keywords.join('|'),
name: Raw((alias) => `${alias} ~* :names`, {
names: searchNameRegexp(keywords),
}),
},
{
year,
code: Raw((alias) => `${alias} ~* :keywords`, {
keywords: keywords.join('|'),
code: Raw((alias) => `${alias} ~* :codes`, {
codes: searchCodeRegexp(keywords),
}),
},
],
Expand Down

0 comments on commit ac2ee4a

Please sign in to comment.