Limit number of search results

This commit is contained in:
Jos de Jong 2020-10-10 14:08:01 +02:00
parent 3f9a7def75
commit adda5836af
5 changed files with 33 additions and 8 deletions

View File

@ -4,7 +4,7 @@
import { debounce } from 'lodash-es'
import Icon from 'svelte-awesome'
import { faCircleNotch, faSearch, faChevronDown, faChevronUp, faTimes } from '@fortawesome/free-solid-svg-icons'
import { DEBOUNCE_DELAY } from '../../constants.js'
import { DEBOUNCE_DELAY, MAX_SEARCH_RESULTS } from '../../constants.js'
import { keyComboFromEvent } from '../../utils/keyBindings.js'
export let text = ''
@ -17,6 +17,10 @@
export let onNext = () => {}
export let onClose = () => {}
$: formattedResultCount = resultCount >= MAX_SEARCH_RESULTS
? `${MAX_SEARCH_RESULTS - 1}+`
: String(resultCount)
$: onChangeDebounced = debounce(onChange, DEBOUNCE_DELAY)
function handleSubmit (event) {
@ -77,7 +81,7 @@
/>
</label>
<div class="search-count" class:visible={text !== ''}>
{activeIndex !== -1 ? `${activeIndex + 1}/` : ''}{resultCount}
{activeIndex !== -1 ? `${activeIndex + 1}/` : ''}{formattedResultCount}
</div>
<button class="search-next" on:click={onNext} type="button">
<Icon data={faChevronDown} />

View File

@ -13,7 +13,8 @@
STATE_LIMIT,
SCROLL_DURATION,
SIMPLE_MODAL_OPTIONS,
SEARCH_PROGRESS_THROTTLE
SEARCH_PROGRESS_THROTTLE,
MAX_SEARCH_RESULTS
} from '../../constants.js'
import { createHistory } from '../../logic/history.js'
import JSONNode from './JSONNode.svelte'
@ -125,7 +126,7 @@ findRootPath
searchHandler = searchAsync(searchText, doc, {
onProgress: handleSearchProgressDebounced,
onDone: handleSearchDone
})
}, 10000, MAX_SEARCH_RESULTS)
}
const history = createHistory({

View File

@ -9,6 +9,7 @@ export const VALIDATION_ERROR = Symbol('validation:error')
export const SCROLL_DURATION = 300 // ms
export const DEBOUNCE_DELAY = 300
export const SEARCH_PROGRESS_THROTTLE = 300 // ms
export const MAX_SEARCH_RESULTS = 1000
export const DEFAULT_LIMIT = 100
export const MAX_PREVIEW_CHARACTERS = 20e3 // characters

View File

@ -109,7 +109,7 @@ async function tick () {
}
// TODO: comment
export function searchAsync (searchText, doc, { onProgress, onDone }, yieldAfterItemCount = 10_000) {
export function searchAsync (searchText, doc, { onProgress, onDone }, yieldAfterItemCount = 10_000, maxResults = Infinity) {
// TODO: what is a good value for yieldAfterItemCount? (larger means faster results but also less responsive during search)
const search = searchGenerator(searchText, doc, yieldAfterItemCount)
@ -129,8 +129,14 @@ export function searchAsync (searchText, doc, { onProgress, onDone }, yieldAfter
do {
next = search.next()
if (next.value) {
if (results.length < maxResults) {
results.push(next.value) // TODO: make this immutable?
newResults = true
} else {
// max results limit reached
cancelled = true
onDone(results)
}
} else {
// time for a small break, give the browser space to do stuff
if (newResults) {

View File

@ -62,7 +62,8 @@ describe('search', () => {
done()
}
searchAsync('4', doc, { onProgress, onDone })
const yieldAfterItemCount = 1
searchAsync('4', doc, { onProgress, onDone }, yieldAfterItemCount)
// should not have results right after creation, but only on the first next tick
assert.deepStrictEqual(callbacks, [])
@ -95,6 +96,18 @@ describe('search', () => {
})
})
it('should limit async search results', (done) => {
const doc = times(30, index => 'item ' + index)
function onDone (results) {
assert.strictEqual(results.length, 10)
done()
}
const maxResults = 10
searchAsync('item', doc, { onDone }, 1000, maxResults)
})
it('should generate recursive search results from flat results', () => {
// Based on document:
const doc = {