mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
fix sort
This commit is contained in:
parent
c8bd953cf3
commit
284697da5b
2 changed files with 64 additions and 57 deletions
|
|
@ -745,8 +745,6 @@ export const updatesSinceResolver = authorized<
|
|||
UpdatesSinceError,
|
||||
QueryUpdatesSinceArgs
|
||||
>(async (_obj, { since, first, after, sort: sortParams, folder }, { uid }) => {
|
||||
const sort = sortParamsToSort(sortParams)
|
||||
|
||||
const startCursor = after || ''
|
||||
const size = Math.min(first || 10, 100) // limit to 100 items
|
||||
let startDate = new Date(since)
|
||||
|
|
@ -754,18 +752,18 @@ export const updatesSinceResolver = authorized<
|
|||
// for android app compatibility
|
||||
startDate = new Date(0)
|
||||
}
|
||||
const sort = sortParamsToSort(sortParams)
|
||||
|
||||
// create a search query
|
||||
const query = `updated:${startDate.toISOString()}${
|
||||
folder ? ' in:' + folder : ''
|
||||
}`
|
||||
} sort:${sort.by}-${sort.order}`
|
||||
|
||||
const { libraryItems, count } = await searchLibraryItems(
|
||||
{
|
||||
from: Number(startCursor),
|
||||
size: size + 1, // fetch one more item to get next cursor
|
||||
includeDeleted: true,
|
||||
sort,
|
||||
query,
|
||||
},
|
||||
uid
|
||||
|
|
|
|||
|
|
@ -94,13 +94,13 @@ export enum SortOrder {
|
|||
}
|
||||
|
||||
export interface Sort {
|
||||
by: SortBy
|
||||
by: string
|
||||
order?: SortOrder
|
||||
}
|
||||
|
||||
interface Select {
|
||||
column: string
|
||||
alias: string
|
||||
alias?: string
|
||||
}
|
||||
|
||||
export const sortParamsToSort = (
|
||||
|
|
@ -153,7 +153,7 @@ export const buildQuery = (
|
|||
searchQuery: LiqeQuery,
|
||||
parameters: ObjectLiteral[] = [],
|
||||
selects: Select[] = [],
|
||||
orders: { by: string; order?: SortOrder }[] = [],
|
||||
orders: Sort[] = [],
|
||||
useFolders = false
|
||||
) => {
|
||||
const escapeQueryWithParameters = (
|
||||
|
|
@ -189,10 +189,8 @@ export const buildQuery = (
|
|||
alias,
|
||||
})
|
||||
|
||||
orders.push({
|
||||
by: alias,
|
||||
order: SortOrder.DESCENDING,
|
||||
})
|
||||
// always sort by rank first
|
||||
orders.unshift({ by: alias, order: SortOrder.DESCENDING })
|
||||
|
||||
return escapeQueryWithParameters(
|
||||
`websearch_to_tsquery('english', :${param}) @@ library_item.search_tsv`,
|
||||
|
|
@ -388,8 +386,20 @@ export const buildQuery = (
|
|||
default: {
|
||||
// check for date ranges
|
||||
const [start, end] = date.split('..')
|
||||
startDate = start && start !== '*' ? new Date(start) : undefined
|
||||
endDate = end && end !== '*' ? new Date(end) : undefined
|
||||
// validate date
|
||||
if (start && start !== '*') {
|
||||
startDate = new Date(start)
|
||||
if (!startDate.getTime()) {
|
||||
throw new Error('Invalid start date.')
|
||||
}
|
||||
}
|
||||
|
||||
if (end && end !== '*') {
|
||||
endDate = new Date(end)
|
||||
if (!endDate.getTime()) {
|
||||
throw new Error('Invalid end date.')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -627,24 +637,29 @@ export const searchLibraryItems = async (
|
|||
args: SearchArgs,
|
||||
userId: string
|
||||
): Promise<{ libraryItems: LibraryItem[]; count: number }> => {
|
||||
const { from = 0, size = 10, sort } = args
|
||||
const { from = 0, size = 10 } = args
|
||||
|
||||
// default order is descending
|
||||
const sortOrder = sort?.order || SortOrder.DESCENDING
|
||||
// default sort by saved_at
|
||||
const sortField = sort?.by || SortBy.SAVED
|
||||
|
||||
const selectColumns = getColumns(libraryItemRepository)
|
||||
.map((column) => `library_item.${column}`)
|
||||
const selects: Select[] = getColumns(libraryItemRepository)
|
||||
.map((column) => ({ column: `library_item.${column}` }))
|
||||
.filter(
|
||||
(column) =>
|
||||
column !== 'library_item.readableContent' &&
|
||||
column !== 'library_item.originalContent'
|
||||
(select) =>
|
||||
select.column !== 'library_item.readableContent' &&
|
||||
select.column !== 'library_item.originalContent'
|
||||
)
|
||||
|
||||
let searchQuery: LiqeQuery | undefined
|
||||
const parameters: ObjectLiteral[] = []
|
||||
const orders: Sort[] = []
|
||||
let query: string | null = null
|
||||
|
||||
if (args.query) {
|
||||
searchQuery = parseSearchQuery(args.query)
|
||||
const searchQuery = parseSearchQuery(args.query)
|
||||
query = buildQuery(
|
||||
searchQuery,
|
||||
parameters,
|
||||
selects,
|
||||
orders,
|
||||
args.useFolders
|
||||
)
|
||||
}
|
||||
|
||||
// add pagination and sorting
|
||||
|
|
@ -652,34 +667,12 @@ export const searchLibraryItems = async (
|
|||
async (tx) => {
|
||||
const queryBuilder = tx
|
||||
.createQueryBuilder(LibraryItem, 'library_item')
|
||||
.select(selectColumns)
|
||||
.where('library_item.user_id = :userId', { userId })
|
||||
|
||||
if (searchQuery) {
|
||||
const parameters: ObjectLiteral[] = []
|
||||
const selects: Select[] = []
|
||||
const orders: Sort[] = []
|
||||
const whereClause = buildQuery(
|
||||
searchQuery,
|
||||
parameters,
|
||||
selects,
|
||||
orders,
|
||||
args.useFolders
|
||||
)
|
||||
whereClause &&
|
||||
queryBuilder
|
||||
.andWhere(whereClause)
|
||||
.setParameters(parameters.reduce((a, b) => ({ ...a, ...b }), {}))
|
||||
|
||||
selects.forEach((select) => {
|
||||
queryBuilder.addSelect(select.column, select.alias)
|
||||
})
|
||||
|
||||
// add order by
|
||||
orders.forEach((order) => {
|
||||
queryBuilder.addOrderBy(order.by, order.order, 'NULLS LAST')
|
||||
})
|
||||
}
|
||||
// add select
|
||||
selects.forEach((select) => {
|
||||
queryBuilder.addSelect(select.column, select.alias)
|
||||
})
|
||||
|
||||
if (!args.includePending) {
|
||||
queryBuilder.andWhere("library_item.state <> 'PROCESSING'")
|
||||
|
|
@ -689,14 +682,30 @@ export const searchLibraryItems = async (
|
|||
queryBuilder.andWhere("library_item.state <> 'DELETED'")
|
||||
}
|
||||
|
||||
const libraryItems = await queryBuilder
|
||||
.addOrderBy(`library_item.${sortField}`, sortOrder, 'NULLS LAST')
|
||||
.skip(from)
|
||||
.take(size)
|
||||
.getMany()
|
||||
if (query) {
|
||||
// add where clause from query
|
||||
queryBuilder
|
||||
.andWhere(query)
|
||||
.setParameters(parameters.reduce((a, b) => ({ ...a, ...b }), {}))
|
||||
}
|
||||
|
||||
const count = await queryBuilder.getCount()
|
||||
|
||||
// default order by saved at descending
|
||||
if (orders.length === 0) {
|
||||
orders.push({
|
||||
by: 'library_item.saved_at',
|
||||
order: SortOrder.DESCENDING,
|
||||
})
|
||||
}
|
||||
|
||||
// add order by
|
||||
orders.forEach((order) => {
|
||||
queryBuilder.addOrderBy(order.by, order.order, 'NULLS LAST')
|
||||
})
|
||||
|
||||
const libraryItems = await queryBuilder.skip(from).take(size).getMany()
|
||||
|
||||
return { libraryItems, count }
|
||||
},
|
||||
undefined,
|
||||
|
|
|
|||
Loading…
Reference in a new issue