Merge pull request #698 from omnivore-app/sort-by-publish-time

Support sort or filter by publish time
This commit is contained in:
Hongbo Wu 2022-05-25 10:41:49 +08:00 committed by GitHub
commit f4c65d7fe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 90 deletions

View file

@ -8,7 +8,7 @@ import {
SearchResponse,
} from './types'
import {
DateRangeFilter,
DateFilter,
HasFilter,
InFilter,
LabelFilter,
@ -145,31 +145,16 @@ const appendIncludeLabelFilter = (
})
}
const appendSavedDateFilter = (
body: SearchBody,
filter: DateRangeFilter
): void => {
body.query.bool.filter.push({
range: {
savedAt: {
gt: filter.startDate,
lt: filter.endDate,
const appendDateFilters = (body: SearchBody, filters: DateFilter[]): void => {
filters.forEach((filter) => {
body.query.bool.filter.push({
range: {
[filter.field]: {
gt: filter.startDate,
lt: filter.endDate,
},
},
},
})
}
const appendPublishedDateFilter = (
body: SearchBody,
filter: DateRangeFilter
): void => {
body.query.bool.filter.push({
range: {
publishedAt: {
gt: filter.startDate,
lt: filter.endDate,
},
},
})
})
}
@ -350,10 +335,9 @@ export const searchPages = async (
inFilter?: InFilter
readFilter?: ReadFilter
typeFilter?: PageType
labelFilters?: LabelFilter[]
hasFilters?: HasFilter[]
savedDateFilter?: DateRangeFilter
publishedDateFilter?: DateRangeFilter
labelFilters: LabelFilter[]
hasFilters: HasFilter[]
dateFilters: DateFilter[]
subscriptionFilter?: SubscriptionFilter
includePending?: boolean | null
},
@ -367,11 +351,10 @@ export const searchPages = async (
query,
readFilter = ReadFilter.ALL,
typeFilter,
labelFilters = [],
labelFilters,
inFilter = InFilter.ALL,
hasFilters = [],
savedDateFilter,
publishedDateFilter,
hasFilters,
dateFilters,
subscriptionFilter,
} = args
// default order is descending
@ -435,11 +418,8 @@ export const searchPages = async (
if (excludeLabels.length > 0) {
appendExcludeLabelFilter(body, excludeLabels)
}
if (savedDateFilter) {
appendSavedDateFilter(body, savedDateFilter)
}
if (publishedDateFilter) {
appendPublishedDateFilter(body, publishedDateFilter)
if (dateFilters.length > 0) {
appendDateFilters(body, dateFilters)
}
if (subscriptionFilter) {
appendSubscriptionFilter(body, subscriptionFilter)

View file

@ -25,12 +25,7 @@ export interface SearchBody {
}
| {
range: {
savedAt: { gt: Date | undefined } | { lt: Date | undefined }
}
}
| {
range: {
publishedAt: { gt: Date | undefined } | { lt: Date | undefined }
[K: string]: { gt: Date | undefined } | { lt: Date | undefined }
}
}
| {

View file

@ -1640,6 +1640,7 @@ export type SignupSuccess = {
};
export enum SortBy {
PublishedAt = 'PUBLISHED_AT',
SavedAt = 'SAVED_AT',
Score = 'SCORE',
UpdatedTime = 'UPDATED_TIME'

View file

@ -1216,6 +1216,7 @@ type SignupSuccess {
}
enum SortBy {
PUBLISHED_AT
SAVED_AT
SCORE
UPDATED_TIME

View file

@ -448,16 +448,7 @@ export const getArticlesResolver = authorized<
event: 'get_articles',
properties: {
env: env.server.apiEnv,
query: searchQuery.query,
inFilter: searchQuery.inFilter,
readFilter: searchQuery.readFilter,
typeFilter: searchQuery.typeFilter,
labelFilters: searchQuery.labelFilters,
sortParams: searchQuery.sortParams,
hasFilters: searchQuery.hasFilters,
savedDateFilter: searchQuery.savedDateFilter,
publishedDateFilter: searchQuery.publishedDateFilter,
subscriptionFilter: searchQuery.subscriptionFilter,
...searchQuery,
},
})
@ -466,16 +457,8 @@ export const getArticlesResolver = authorized<
from: Number(startCursor),
size: first + 1, // fetch one more item to get next cursor
sort: searchQuery.sortParams,
query: searchQuery.query,
inFilter: searchQuery.inFilter,
readFilter: searchQuery.readFilter,
typeFilter: searchQuery.typeFilter,
labelFilters: searchQuery.labelFilters,
hasFilters: searchQuery.hasFilters,
savedDateFilter: searchQuery.savedDateFilter,
publishedDateFilter: searchQuery.publishedDateFilter,
subscriptionFilter: searchQuery.subscriptionFilter,
includePending: params.includePending,
...searchQuery,
},
claims.uid
)) || [[], 0]
@ -818,16 +801,8 @@ export const searchResolver = authorized<
userId: claims.uid,
event: 'search',
properties: {
query: searchQuery.query,
inFilter: searchQuery.inFilter,
readFilter: searchQuery.readFilter,
typeFilter: searchQuery.typeFilter,
labelFilters: searchQuery.labelFilters,
sortParams: searchQuery.sortParams,
hasFilters: searchQuery.hasFilters,
savedDateFilter: searchQuery.savedDateFilter,
publishedDateFilter: searchQuery.publishedDateFilter,
env: env.server.apiEnv,
...searchQuery,
},
})
@ -853,16 +828,8 @@ export const searchResolver = authorized<
from: Number(startCursor),
size: first + 1, // fetch one more item to get next cursor
sort: searchQuery.sortParams,
query: searchQuery.query,
inFilter: searchQuery.inFilter,
readFilter: searchQuery.readFilter,
typeFilter: searchQuery.typeFilter,
labelFilters: searchQuery.labelFilters,
hasFilters: searchQuery.hasFilters,
savedDateFilter: searchQuery.savedDateFilter,
publishedDateFilter: searchQuery.publishedDateFilter,
subscriptionFilter: searchQuery.subscriptionFilter,
includePending: true,
...searchQuery,
},
claims.uid
)) || [[], 0]

View file

@ -29,6 +29,7 @@ const schema = gql`
UPDATED_TIME
SCORE
SAVED_AT
PUBLISHED_AT
}
enum ContentReader {

View file

@ -31,8 +31,7 @@ export type SearchFilter = {
labelFilters: LabelFilter[]
sortParams?: SortParams
hasFilters: HasFilter[]
savedDateFilter?: DateRangeFilter
publishedDateFilter?: DateRangeFilter
dateFilters: DateFilter[]
subscriptionFilter?: SubscriptionFilter
}
@ -51,7 +50,8 @@ export enum HasFilter {
SHARED_AT,
}
export type DateRangeFilter = {
export interface DateFilter {
field: string
startDate?: Date
endDate?: Date
}
@ -60,6 +60,7 @@ export enum SortBy {
SAVED = 'savedAt',
UPDATED = 'updatedAt',
SCORE = '_score',
PUBLISHED = 'publishedAt',
}
export enum SortOrder {
@ -67,7 +68,7 @@ export enum SortOrder {
DESCENDING = 'desc',
}
export type SortParams = {
export interface SortParams {
by: SortBy
order?: SortOrder
}
@ -171,6 +172,11 @@ const parseSortParams = (str?: string): SortParams | undefined => {
return {
by: SortBy.SCORE,
}
case 'PUBLISHED':
return {
by: SortBy.PUBLISHED,
order: sortOrder,
}
}
}
@ -185,7 +191,10 @@ const parseHasFilter = (str?: string): HasFilter | undefined => {
}
}
const parseDateRangeFilter = (str?: string): DateRangeFilter | undefined => {
const parseDateFilter = (
field: string,
str?: string
): DateFilter | undefined => {
if (str === undefined) {
return undefined
}
@ -194,7 +203,16 @@ const parseDateRangeFilter = (str?: string): DateRangeFilter | undefined => {
const startDate = start && start !== '*' ? new Date(start) : undefined
const endDate = end && end !== '*' ? new Date(end) : undefined
switch (field.toUpperCase()) {
case 'PUBLISHED':
field = 'publishedAt'
break
case 'SAVED':
field = 'savedAt'
}
return {
field,
startDate,
endDate,
}
@ -220,6 +238,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
inFilter: searchQuery ? InFilter.ALL : InFilter.INBOX,
labelFilters: [],
hasFilters: [],
dateFilters: [],
}
if (!searchQuery) {
@ -229,6 +248,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
readFilter: ReadFilter.ALL,
labelFilters: [],
hasFilters: [],
dateFilters: [],
}
}
@ -296,11 +316,11 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
break
}
case 'saved':
result.savedDateFilter = parseDateRangeFilter(keyword.value)
break
case 'published':
result.publishedDateFilter = parseDateRangeFilter(keyword.value)
case 'published': {
const dateFilter = parseDateFilter(keyword.keyword, keyword.value)
dateFilter && result.dateFilters.push(dateFilter)
break
}
case 'subscription':
result.subscriptionFilter = parseSubscriptionFilter(keyword.value)
break

View file

@ -148,6 +148,8 @@ describe('elastic api', () => {
it('searches pages', async () => {
const searchResults = await searchPages(
{
dateFilters: [],
hasFilters: [],
inFilter: InFilter.ALL,
labelFilters: [],
readFilter: ReadFilter.ALL,