feat(search): omit default sort while searching so results rank by relevance
The web client always sent sort_by/order_by (the view's default sort), so the backend's userProvidedSort flag was always true and the new BM25 relevance ranking never engaged from the web app. When a search is active and the user has not explicitly chosen a sort, omit the sort entirely so the backend ranks results by relevance. An explicit user sort still suppresses ranking and non-search browsing is unchanged.
This commit is contained in:
parent
6f6f91bd28
commit
a2cb2826d0
|
|
@ -0,0 +1,83 @@
|
|||
import {describe, it, expect, beforeEach, vi} from 'vitest'
|
||||
import {defineComponent, h, nextTick} from 'vue'
|
||||
import {mount, flushPromises} from '@vue/test-utils'
|
||||
import {setActivePinia, createPinia} from 'pinia'
|
||||
import {createRouter, createMemoryHistory, type Router} from 'vue-router'
|
||||
|
||||
const getAll = vi.fn(async () => [])
|
||||
vi.mock('@/services/taskCollection', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/services/taskCollection')>()
|
||||
return {
|
||||
...actual,
|
||||
default: class {
|
||||
loading = false
|
||||
totalPages = 1
|
||||
getAll = getAll
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
import {useTaskList} from './useTaskList'
|
||||
|
||||
// The second positional argument passed to TaskCollectionService.getAll carries
|
||||
// the sort_by/order_by the backend uses to decide whether to rank by relevance.
|
||||
function lastRequestParams(): Record<string, unknown> {
|
||||
return getAll.mock.calls.at(-1)?.[1] as Record<string, unknown>
|
||||
}
|
||||
|
||||
async function mountTaskList(query: Record<string, string>): Promise<Router> {
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [{path: '/', name: 'home', component: {render: () => null}}],
|
||||
})
|
||||
await router.push({path: '/', query})
|
||||
await router.isReady()
|
||||
|
||||
const TestComponent = defineComponent({
|
||||
setup() {
|
||||
useTaskList(() => 1, () => 1)
|
||||
return () => h('div')
|
||||
},
|
||||
})
|
||||
|
||||
mount(TestComponent, {global: {plugins: [router]}})
|
||||
await flushPromises()
|
||||
await nextTick()
|
||||
return router
|
||||
}
|
||||
|
||||
describe('useTaskList sort handling for relevance ranking', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
getAll.mockClear()
|
||||
})
|
||||
|
||||
it('omits the sort while searching with the default sort so the backend ranks by relevance', async () => {
|
||||
await mountTaskList({s: 'find me'})
|
||||
|
||||
const params = lastRequestParams()
|
||||
expect(params.s).toBe('find me')
|
||||
expect(params.sort_by).toEqual([])
|
||||
expect(params.order_by).toEqual([])
|
||||
})
|
||||
|
||||
it('keeps an explicit user sort while searching so the user sort is respected', async () => {
|
||||
await mountTaskList({s: 'find me', sort: 'title:asc'})
|
||||
|
||||
const params = lastRequestParams()
|
||||
expect(params.s).toBe('find me')
|
||||
expect(params.sort_by).toEqual(['title'])
|
||||
expect(params.order_by).toEqual(['asc'])
|
||||
})
|
||||
|
||||
it('sends the default sort when not searching', async () => {
|
||||
await mountTaskList({})
|
||||
|
||||
const params = lastRequestParams()
|
||||
expect(params.s).toBe('')
|
||||
expect(params.sort_by).not.toHaveLength(0)
|
||||
// id always sorts last so other sort columns take precedence.
|
||||
expect(params.sort_by).toEqual(['id'])
|
||||
expect(params.order_by).toEqual(['desc'])
|
||||
})
|
||||
})
|
||||
|
|
@ -122,6 +122,14 @@ export function useTaskList(
|
|||
const allParams = computed(() => {
|
||||
const loadParams = {...params.value}
|
||||
|
||||
// Relevance ranking only engages when no sort is sent, so omit the default
|
||||
// sort while searching and let an explicit user sort still take precedence.
|
||||
if (loadParams.s && !sortQuery.value) {
|
||||
loadParams.sort_by = []
|
||||
loadParams.order_by = []
|
||||
return loadParams
|
||||
}
|
||||
|
||||
return formatSortOrder(sortBy.value, loadParams)
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue