Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api): opensearch add s/u filter #650

Draft
wants to merge 9 commits into
base: beta
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/red-baboons-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'api': minor
---

fix: implement s/u filter in search
4 changes: 3 additions & 1 deletion apps/api/src/course/course.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { isTime } from '@api/util/functions'

import { Course, CourseDocument, DayOfWeek, GenEdType, Semester, StudyProgram } from '@cgr/schema'

import { CourseGroupInput, FilterInput, Period } from '../graphql'
import { CourseGroupInput, FilterInput, GradingType, Period } from '../graphql'
import { CourseService } from './course.service'

export interface ICourseSearchDocument {
Expand All @@ -29,6 +29,7 @@ export interface ICourseSearchDocument {
export interface ICourseSearchFilter {
keyword: string
genEdTypes?: GenEdType[]
gradingTypes?: GradingType[]
dayOfWeeks?: DayOfWeek[]
periodRange: Period
studyProgram: string
Expand Down Expand Up @@ -92,6 +93,7 @@ export class CourseResolver {
keyword: filter.keyword,
genEdTypes: filter.genEdTypes,
dayOfWeeks: filter.dayOfWeeks,
gradingTypes: filter.gradingTypes,
periodRange: filter.periodRange,
studyProgram: courseGroup.studyProgram,
semester: courseGroup.semester,
Expand Down
21 changes: 18 additions & 3 deletions apps/api/src/search/queries/course.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { ICourseSearchFilter } from '@api/course/course.resolver'

// build the query
export function buildCourseQuery(filter: ICourseSearchFilter): Record<string, any> {

Check warning on line 4 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type
// create the base query from values that guarantee is not undefined
const boolMust: Record<string, any>[] = []

Check warning on line 6 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type
const boolMustNot: Record<string, any>[] = []

Check warning on line 7 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type
const boolFilter: Record<string, any>[] = []

Check warning on line 8 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type

if (filter.keyword) {
boolMust.push({
Expand All @@ -21,7 +23,7 @@
})
}

const sectionsQuery: Record<string, any>[] = []

Check warning on line 26 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type

// push the query for each filter if filter is not undefined
if (filter.dayOfWeeks?.length > 0) {
Expand Down Expand Up @@ -53,6 +55,21 @@
})
}

const containsSU = filter.gradingTypes?.includes('S_U')
const containsLetter = filter.gradingTypes?.includes('LETTER')

if (filter.gradingTypes?.length > 0 && !(containsSU && containsLetter)) {
if (containsSU) {
boolFilter.push({
wildcard: { creditHours: { value: '*(S/U)*' } },
})
} else if (containsLetter) {
boolMustNot.push({
wildcard: { creditHours: { value: '*(S/U)*' } },
})
}
}

if (sectionsQuery.length > 0) {
boolMust.push({
nested: {
Expand All @@ -76,7 +93,7 @@
})
}

const result: Record<string, any> = {

Check warning on line 96 in apps/api/src/search/queries/course.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest) / run

Unexpected any. Specify a different type
bool: {
filter: [
{
Expand Down Expand Up @@ -104,9 +121,7 @@
},
}

if (boolMust.length > 0) {
result['bool'] = { must: boolMust }
}
result['bool'] = { must: boolMust, must_not: boolMustNot, filter: boolFilter }

return result
}
39 changes: 39 additions & 0 deletions apps/opensearch-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,42 @@ go run ./cli/app.go index create --index-name=<index name> --filename=<filename>
```shell
go run ./cli/app.go index create --index-name=course-dev-1 --filename=dev/course-index.json
```

# Reindex

```shell
go run ./cli/app.go index reindex --index-name=<source index name> --dest=<dest index name> --debug=<true/false>
```

| name | description |
| ---------- | ---------------------------------- |
| index name | name of index |
| dest | name of destination index |
| debug | enable debug mode (`true`/`false`) |

## Example

### Reindex from course-dev-1 to course-dev-2

```shell
go run ./cli/app.go index reindex --index-name=course-dev-1 --dest=course-dev-2
```

# Delete Index

```shell
go run ./cli/app.go index reindex --index-name=<source index name> --dest=<dest index name> --debug=<true/false>
```

| name | description |
|------------|------------------------------------|
| index name | name of index |
| debug | enable debug mode (`true`/`false`) |

## Example

### Delete index course-dev-1

```shell
go run ./cli/app.go index delete --index-name=course-dev-1
```
87 changes: 87 additions & 0 deletions apps/opensearch-cli/cli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"encoding/json"
"flag"
"fmt"
"github.com/opensearch-project/opensearch-go/v2"
Expand All @@ -18,6 +19,7 @@ import (
var (
fileName string
indexName string
destName string
isDebug bool
indexCmd *flag.FlagSet
)
Expand All @@ -28,6 +30,7 @@ func init() {
indexCmd = flag.NewFlagSet("index", flag.ExitOnError)

indexCmd.StringVar(&indexName, "index-name", "", "Index name")
indexCmd.StringVar(&destName, "dest", "", "Destination index name")
indexCmd.StringVar(&fileName, "filename", "", "Index filename")
indexCmd.BoolVar(&isDebug, "debug", false, "Enable the debug log")
flag.Parse()
Expand Down Expand Up @@ -74,6 +77,26 @@ func main() {

fmt.Println(strings.Repeat("_", 65))
fmt.Printf("successfully create the index, %s \n", indexName)
case "reindex":
if err := handleReindex(client); err != nil {
logger.Fatal(
"Error while creating the index",
zap.Error(err),
)
}

fmt.Println(strings.Repeat("_", 65))
fmt.Printf("successfully reindex from %s to %s \n", indexName, destName)
case "delete":
if err := handleDeleteIndex(client); err != nil {
logger.Fatal(
"Error while creating the index",
zap.Error(err),
)
}

fmt.Println(strings.Repeat("_", 65))
fmt.Printf("successfully delete the index, %s \n", indexName)
default:
logger.Fatal("Invalid input (invalid command)")
}
Expand Down Expand Up @@ -146,3 +169,67 @@ func handleCreateIndex(client *opensearch.Client) error {

return nil
}

type ReIndexBody struct {
Source struct {
Index string `json:"index"`
} `json:"source"`

Dest struct {
Index string `json:"index"`
} `json:"dest"`
}

func handleReindex(client *opensearch.Client) error {
if err := indexCmd.Parse(os.Args[3:]); err != nil {
return err
}

req, err := json.Marshal(ReIndexBody{
Source: struct {
Index string `json:"index"`
}{Index: indexName},

Dest: struct {
Index string `json:"index"`
}{Index: destName},
})

if err != nil {
return err
}

res, err := client.Reindex(
bytes.NewReader(req),
)

if err != nil {
return err
}

if res.IsError() {
return errors.New(res.String())
}

return nil
}

func handleDeleteIndex(client *opensearch.Client) error {
if err := indexCmd.Parse(os.Args[3:]); err != nil {
return err
}

res, err := client.Indices.Delete(
[]string{indexName},
)

if err != nil {
return err
}

if res.IsError() {
return errors.New(res.String())
}

return nil
}
5 changes: 5 additions & 0 deletions apps/opensearch-cli/docs/reindex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Reindex Guideline

1. Create new index (destination index) by using command `go run ./cli/app.go index create --index-name=<new index name> --filename=<file path>`
2. Run reindex command `go run ./cli/app.go index reindex --index-name=<old index name> --dest=<new index name>`
3. Delete the old one `go run ./cli/app.go index delete --index-name=<old index name>`
8 changes: 7 additions & 1 deletion apps/opensearch-cli/index/beta/course-index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"aliases": {
"course-beta": {}
"cgr-course-beta": {}
},
"settings": {
"index": {
Expand Down Expand Up @@ -73,6 +73,9 @@
}
}
},
"suggestions": {
"type": "completion"
},
"abbrName": {
"type": "text",
"analyzer": "courseabbranal"
Expand Down Expand Up @@ -106,6 +109,9 @@
},
"academicYear": {
"type": "keyword"
},
"creditHours": {
"type": "keyword"
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion apps/opensearch-cli/index/dev/course-index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"aliases": {
"course-dev": {}
"cgr-course-dev": {}
},
"settings": {
"index": {
Expand Down Expand Up @@ -73,6 +73,9 @@
}
}
},
"suggestions": {
"type": "completion"
},
"abbrName": {
"type": "text",
"analyzer": "courseabbranal"
Expand Down Expand Up @@ -106,6 +109,9 @@
},
"academicYear": {
"type": "keyword"
},
"creditHours": {
"type": "keyword"
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion apps/opensearch-cli/index/prod/course-index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"aliases": {
"course-prod": {}
"cgr-course-prod": {}
},
"settings": {
"index": {
Expand Down Expand Up @@ -73,6 +73,9 @@
}
}
},
"suggestions": {
"type": "completion"
},
"abbrName": {
"type": "text",
"analyzer": "courseabbranal"
Expand Down Expand Up @@ -106,6 +109,9 @@
},
"academicYear": {
"type": "keyword"
},
"creditHours": {
"type": "keyword"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface CourseDoc {
studyProgram: StudyProgram
semester: Semester
academicYear: string
creditHours: string
}

@Processor({
Expand Down Expand Up @@ -76,6 +77,13 @@ export class QueueConsumerService {
genEdType: course.genEdType,
semester: course.semester,
studyProgram: course.studyProgram,
creditHours: course.creditHours,
suggestions: [
{
input: [course.courseNo, course.abbrName, course.courseNameEn, course.courseNameTh],
weight: 20,
},
],
} as CourseDoc,
doc_as_upsert: true,
},
Expand Down
Loading