limit irrelevant blocks in search

This commit is contained in:
amirhouieh 2023-05-15 19:37:47 +02:00 committed by Jinho Jang
parent 1fc5094a75
commit 61971e2426
9 changed files with 70 additions and 29 deletions

View File

@ -1,7 +1,6 @@
import { Tag } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
import { nope } from '@/utils/general.utils'
import Link from 'next/link'
type FilterTagsProps = {
tags: string[]
@ -11,6 +10,7 @@ type FilterTagsProps = {
export default function FilterTags(props: FilterTagsProps) {
const { tags = [], onTagClick = nope, selectedTags } = props
return (
<Container>
<Tags>
@ -22,7 +22,7 @@ export default function FilterTags(props: FilterTagsProps) {
onClick={() => onTagClick(tag)}
variant={selectedTags.includes(tag) ? 'filled' : 'outlined'}
>
<Link href={`/search?topics=${tag}`}>{tag}</Link>
{tag}
</Tag>
))}
</Tags>
@ -62,8 +62,4 @@ const Tags = styled.div`
padding-right: 16px;
}
a {
text-decoration: none;
}
`

View File

@ -4,11 +4,16 @@ import { useSearchBarContext } from '@/context/searchbar.context'
import { useRouter } from 'next/router'
export const NavbarFiller = () => {
const router = useRouter()
const { tags } = useSearchBarContext()
const onTagClick = (tag: string) => {
router.push(`/search?topics=${tag}`)
}
return (
<NavbarFillerContainer>
<FilterTags onTagClick={() => {}} tags={tags} selectedTags={[]} />
<FilterTags onTagClick={onTagClick} tags={tags} selectedTags={[]} />
</NavbarFillerContainer>
)
}

View File

@ -118,10 +118,10 @@ export default function Searchbar(props: SearchbarProps) {
}
}
const isCollapsed = isValidSearchInput() && !active
const isCollapsed = isValidSearchInput(filterTags) && !active
useEffect(() => {
if (active) {
if (active && query.length > 0) {
setPlaceholder('')
} else {
setTimeout(() => {

View File

@ -25,7 +25,7 @@ export const useSearchGeneric = <T>(
const search = async (query: string, tags: string[]) => {
if (loading) return Promise.resolve([])
setLoading(true)
const result = await searchApi.serach(query, tags, postType)
const result = await searchApi.search(query, tags, postType)
setData(result.data)
setLoading(false)
return result.data

View File

@ -19,6 +19,7 @@ import { RelatedContent } from '@/components/RelatedContent'
import { Section } from '@/components/Section/Section'
import api from '@/services/unbody.service'
import { useSearchBarContext } from '@/context/searchbar.context'
import { shuffle } from '@/utils/data.utils'
interface SearchPageProps {
articles: SearchResultItem<UnbodyGoogleDoc>[]
@ -63,11 +64,15 @@ export default function SearchPage({
}, [])
useEffect(() => {
if (mounted) {
const serchArgs = [
extractQueryFromQuery(router.query),
extractTopicsFromQuery(router.query),
]
const serchArgs = [
extractQueryFromQuery(router.query),
extractTopicsFromQuery(router.query),
]
const hasQuery = router.query.query && router.query.query.length > 0
const hasTopics = router.query.topics && router.query.topics.length > 0
if (mounted && (hasQuery || hasTopics)) {
articles.search(...(serchArgs as [string, string[]]))
blocks.search(...(serchArgs as [string, string[]]))
} else {
@ -83,7 +88,7 @@ export default function SearchPage({
const tags = extractTopicsFromQuery(router.query)
setResultsHelperText(
[
query,
...(query.length > 0 ? [query] : []),
topics.length > 0
? `<span class="tags">${tags
.map((t) => `<span>[${t}]</span>`)
@ -113,7 +118,7 @@ export async function getStaticProps() {
return {
props: {
articles,
blocks,
blocks: shuffle(blocks),
topics,
},
}

View File

@ -28,6 +28,7 @@ export const getSearchBlocksQuery = (args: UnbodyGetFilters = defaultArgs) =>
}
_additional{
certainty
score
id
}
`),
@ -49,6 +50,7 @@ export const getSearchBlocksQuery = (args: UnbodyGetFilters = defaultArgs) =>
}
_additional{
certainty
score
id
}
`),

View File

@ -3,7 +3,11 @@ import { PostTypes } from '@/types/data.types'
class SearchService {
constructor() {}
serach = (query: string, tags: string[], postType: PostTypes) => {
search = (query: string, tags: string[], postType: PostTypes) => {
console.log(
`/api/search/general/${postType}?q=${query}&tags=${tags.join(',')}`,
)
return fetch(
`/api/search/general/${postType}?q=${query}&tags=${tags.join(',')}`,
)

View File

@ -331,7 +331,7 @@ class UnbodyService extends UnbodyClient {
? {
nearText: {
concepts: [q, ...tags],
certainty: 0.8,
certainty: 0.85,
},
where: {
operator: UnbodyGraphQl.Filters.WhereOperatorEnum.And,
@ -386,21 +386,30 @@ class UnbodyService extends UnbodyClient {
): Promise<
ApiResponse<SearchResultItem<UnbodyImageBlock | UnbodyTextBlock>[]>
> => {
const query = getSearchBlocksQuery({
...(q.trim().length > 0
const nearTextFilters =
q.trim().length > 0 || tags.length > 0
? {
nearText: {
concepts: [q, ...tags],
concepts: [q, ...tags].filter((t) => t.trim().length > 0),
certainty: 0.85,
},
where: Operands.WHERE_PUBLISHED([
'document',
UnbodyGraphQl.UnbodyDocumentTypeNames.GoogleDoc,
'pathString',
]),
limit: 20,
}
: { limit: 20 }),
: {}
const whereFilters = published
? {
where: Operands.WHERE_PUBLISHED([
'document',
UnbodyGraphQl.UnbodyDocumentTypeNames.GoogleDoc,
'pathString',
]),
}
: {}
const query = getSearchBlocksQuery({
...nearTextFilters,
...whereFilters,
limit: 20,
})
return this.request<UnbodyGraphQlResponseBlocks>(query)

View File

@ -79,3 +79,23 @@ export const getArticleCover = (
) as UnbodyImageBlock) || null
)
}
export const shuffle = (array: any[]) => {
let currentIndex = array.length,
randomIndex
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex--
// And swap it with the current element.
;[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
]
}
return array
}