1
0

fix(tasks): index and order by task position when using typesense

This commit is contained in:
kolaente 2024-04-13 17:19:27 +02:00
parent cb648e5ad8
commit 3519b8b2fe
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
3 changed files with 47 additions and 17 deletions

View File

@ -249,12 +249,21 @@ func (tf *TaskCollection) ReadAll(s *xorm.Session, a web.Auth, search string, pa
opts.perPage = perPage opts.perPage = perPage
if view != nil { if view != nil {
var hasOrderByPosition bool
for _, param := range opts.sortby {
if param.sortBy == taskPropertyPosition {
hasOrderByPosition = true
break
}
}
if !hasOrderByPosition {
opts.sortby = append(opts.sortby, &sortParam{ opts.sortby = append(opts.sortby, &sortParam{
projectViewID: view.ID, projectViewID: view.ID,
sortBy: taskPropertyPosition, sortBy: taskPropertyPosition,
orderBy: orderAscending, orderBy: orderAscending,
}) })
} }
}
shareAuth, is := a.(*LinkSharing) shareAuth, is := a.(*LinkSharing)
if is { if is {

View File

@ -450,6 +450,7 @@ func (t *typesenseTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task,
"(" + filter + ")", "(" + filter + ")",
} }
var projectViewIDForPosition int64
var sortbyFields []string var sortbyFields []string
for i, param := range opts.sortby { for i, param := range opts.sortby {
// Validate the params // Validate the params
@ -457,17 +458,19 @@ func (t *typesenseTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task,
return nil, totalCount, err return nil, totalCount, err
} }
sortBy := param.sortBy
// Typesense does not allow sorting by ID, so we sort by created timestamp instead // Typesense does not allow sorting by ID, so we sort by created timestamp instead
if param.sortBy == taskPropertyID { if param.sortBy == taskPropertyID {
param.sortBy = taskPropertyCreated sortBy = taskPropertyCreated
} }
if param.sortBy == taskPropertyPosition { if param.sortBy == taskPropertyPosition {
param.sortBy = "positions.view_" + strconv.FormatInt(param.projectViewID, 10) sortBy = "positions.view_" + strconv.FormatInt(param.projectViewID, 10)
continue projectViewIDForPosition = param.projectViewID
} }
sortbyFields = append(sortbyFields, param.sortBy+"(missing_values:last):"+param.orderBy.String()) sortbyFields = append(sortbyFields, sortBy+"(missing_values:last):"+param.orderBy.String())
if i == 2 { if i == 2 {
// Typesense supports up to 3 sorting parameters // Typesense supports up to 3 sorting parameters
@ -525,9 +528,14 @@ func (t *typesenseTaskSearcher) Search(opts *taskSearchOptions) (tasks []*Task,
return nil, 0, err return nil, 0, err
} }
err = t.s. query := t.s.
In("id", taskIDs). In("id", taskIDs).
OrderBy(orderby). OrderBy(orderby)
Find(&tasks)
if projectViewIDForPosition != 0 {
query = query.Join("LEFT", "task_positions", "task_positions.task_id = tasks.id AND task_positions.project_view_id = ?", projectViewIDForPosition)
}
err = query.Find(&tasks)
return tasks, int64(*result.Found), err return tasks, int64(*result.Found), err
} }

View File

@ -240,9 +240,18 @@ func ReindexAllTasks() (err error) {
return return
} }
type TaskPositionWithView struct {
ProjectView `xorm:"extends"`
TaskPosition `xorm:"extends"`
}
func getTypesenseTaskForTask(s *xorm.Session, task *Task, projectsCache map[int64]*Project) (ttask *typesenseTask, err error) { func getTypesenseTaskForTask(s *xorm.Session, task *Task, projectsCache map[int64]*Project) (ttask *typesenseTask, err error) {
positions := []*TaskPosition{} positions := []*TaskPositionWithView{}
err = s.Where("task_id = ?", task.ID).Find(&positions) err = s.
Table("project_views").
Where("project_views.project_id = ?", task.ProjectID).
Join("LEFT", "task_positions", "project_views.id = task_positions.project_view_id AND task_positions.task_id = ?", task.ID).
Find(&positions)
if err != nil { if err != nil {
return return
} }
@ -312,7 +321,7 @@ func reindexTasksInTypesense(s *xorm.Session, tasks map[int64]*Task) (err error)
return err return err
} }
log.Debugf("Indexed tasks %v into Typesense", tasks) log.Debugf("Indexed %d tasks into Typesense", len(tasks))
return nil return nil
} }
@ -430,7 +439,7 @@ type typesenseTask struct {
Positions map[string]float64 `json:"positions"` Positions map[string]float64 `json:"positions"`
} }
func convertTaskToTypesenseTask(task *Task, positions []*TaskPosition) *typesenseTask { func convertTaskToTypesenseTask(task *Task, positions []*TaskPositionWithView) *typesenseTask {
tt := &typesenseTask{ tt := &typesenseTask{
ID: fmt.Sprintf("%d", task.ID), ID: fmt.Sprintf("%d", task.ID),
@ -476,7 +485,11 @@ func convertTaskToTypesenseTask(task *Task, positions []*TaskPosition) *typesens
} }
for _, position := range positions { for _, position := range positions {
tt.Positions["view_"+strconv.FormatInt(position.ProjectViewID, 10)] = position.Position pos := position.TaskPosition.Position
if pos == 0 {
pos = float64(task.ID)
}
tt.Positions["view_"+strconv.FormatInt(position.ProjectView.ID, 10)] = pos
} }
return tt return tt