Add no: keyword to the search filter to filter items without label or highlight

This commit is contained in:
Hongbo Wu
2023-02-17 12:48:02 +08:00
parent 153ca6995b
commit 214766dda6
3 changed files with 62 additions and 0 deletions

View File

@ -15,6 +15,7 @@ import {
InFilter,
LabelFilter,
LabelFilterType,
NoFilter,
ReadFilter,
SortBy,
SortOrder,
@ -208,6 +209,21 @@ const appendRecommendedBy = (body: SearchBody, recommendedBy: string): void => {
})
}
const appendNoFilters = (body: SearchBody, noFilters: NoFilter[]): void => {
noFilters.forEach((filter) => {
body.query.bool.must_not.push({
nested: {
path: filter.field,
query: {
exists: {
field: filter.field,
},
},
},
})
})
}
export const createPage = async (
page: Page,
ctx: PageContext
@ -389,6 +405,7 @@ export const searchPages = async (
matchFilters,
ids,
includeContent,
noFilters,
} = args
// default order is descending
const sortOrder = sort?.order || SortOrder.DESCENDING
@ -484,6 +501,10 @@ export const searchPages = async (
})
}
if (noFilters) {
appendNoFilters(body, noFilters)
}
console.log('searching pages in elastic', JSON.stringify(body))
const response = await client.search<SearchResponse<Page>, SearchBody>({

View File

@ -7,6 +7,7 @@ import {
HasFilter,
InFilter,
LabelFilter,
NoFilter,
ReadFilter,
SortParams,
} from '../utils/search'
@ -106,6 +107,16 @@ export interface SearchBody {
}
}
}
| {
nested: {
path: string
query: {
exists: {
field: string
}
}
}
}
)[]
}
}
@ -317,4 +328,5 @@ export interface PageSearchArgs {
ids?: string[]
recommendedBy?: string
includeContent?: boolean
noFilters?: NoFilter[]
}

View File

@ -36,6 +36,7 @@ export interface SearchFilter {
matchFilters: FieldFilter[]
ids: string[]
recommendedBy?: string
noFilters: NoFilter[]
}
export enum LabelFilterType {
@ -83,6 +84,10 @@ export interface FieldFilter {
value: string
}
export interface NoFilter {
field: string
}
const parseRecommendedBy = (str?: string): string | undefined => {
if (str === undefined) {
return undefined
@ -263,6 +268,22 @@ const parseIds = (field: string, str?: string): string[] | undefined => {
return str.split(',')
}
const parseNoFilter = (str?: string): NoFilter | undefined => {
if (str === undefined) {
return undefined
}
const strLower = str.toLowerCase()
const accepted = ['highlight', 'label']
if (accepted.includes(strLower)) {
return {
field: `${strLower}s`,
}
}
return undefined
}
export const parseSearchQuery = (query: string | undefined): SearchFilter => {
const searchQuery = query ? query.replace(/\W\s":/g, '') : undefined
const result: SearchFilter = {
@ -275,6 +296,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
termFilters: [],
matchFilters: [],
ids: [],
noFilters: [],
}
if (!searchQuery) {
@ -288,6 +310,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
termFilters: [],
matchFilters: [],
ids: [],
noFilters: [],
}
}
@ -310,6 +333,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
'updated',
'includes',
'recommendedBy',
'no',
],
tokenize: true,
})
@ -395,6 +419,11 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => {
result.recommendedBy = parseRecommendedBy(keyword.value)
break
}
case 'no': {
const noFilter = parseNoFilter(keyword.value)
noFilter && result.noFilters.push(noFilter)
break
}
}
}
}