brianreavis / sifter.js

A library for textually searching arrays and hashes of objects by property (or multiple properties). Designed specifically for autocomplete.
1.09k stars 125 forks source link

Possible to stop a search in progress #46

Closed Wyzix33 closed 7 years ago

Wyzix33 commented 7 years ago

Hi, i am trying to create a small autocomplete without jquery that can handle large amount of options, 500k+, i have a problem where about 200k+ are starting with the same word, if i start typing that word it blocks the ui for a long time, so i was wandering if there is a way to stop the search if it passes over the limit number of results with score over 1.0 i get score 1.1 for all. Or to be able to stop the search manually, or after a fixed amount of time and return only the results that it got until stop was triggered.

Thanks, and great work with this library.

broerse commented 7 years ago

You can override the getSortFunction like this and detect where to stop. Not sure how to kill the running sifter.

https://github.com/lazybensch/ember-cli-filter-by-query/blob/master/addon/util/filter.js#L33

brianreavis commented 7 years ago

Sifter was designed to be synchronous. Making it break the task into chunks and do a non-blocking sort would be a pretty large endeavor. I'd suggest looking into Web Workers

Wyzix33 commented 7 years ago

Hi, it is already running inside a worker, it get's the options by XMLHttpRequest and i keep the worker running in parallel with the main UI thread, i only send the search string and options to the worker and listen for the response, but the search in this case takes about 19 seconds to return some results and until then my search autocomplete is not working, and since it's impossible to choose from about 100k results that all has the same Sifter score i just want to stop after first 30 or so with a minimum score of 1.0 or 1.1 and display those until the search string is larger and it gets fewer results, i am now trying to override the getSortFunction, i'll post here if i succeed

Wyzix33 commented 7 years ago

I think i got it, the sort was the problem... so i made a small function that overrides the getSortFunction and only sort the results if there are less than 200, now everything is instant but i only get sorted results only if there are less than 200. I will test some more, hope there won't be any problems.

        var old = Sifter.prototype.getSortFunction;
    Sifter.prototype.getSortFunction = function(search, options) {      
        if(search.items.length > 200) options.sort = null;
        return old.call(this,search, options);
    }

Now i don't need to stop it anymore 👍 Here are some tests results over 1.000.000 options containing 6 properties 10-50 characters each and one commune word , 2 sortFields and around 120 MB in download size taking around 4 seconds to download from server Call to search took 1242.425000000001 milliseconds for a total of 1000000 options returning 1000000 results after search, before limit. Call to search took 229.30999999999767 milliseconds for a total of 1000000 options returning 111111 results after search, before limit. Call to search took 213.25500000000466 milliseconds for a total of 1000000 options returning 3999 results after search, before limit. Call to search took 216.32000000000698 milliseconds for a total of 1000000 options returning 11 results after search, before limit. Thanks @broerse for your hint and thanks @brianreavis for sharing this library