对 JavaScript 的简单、无索引的全文搜索
Simple, index-free text search for JavaScript, used across my personal projects like YC Vibe Check, linus.zone/entr, and my personal productivity software. Read the annotated source to understand how it works under the hood.
Let's begin with some quick examples:
…
More formally, libsearch exposes a single API, the search function. This function takes two required arguments and two optional arguments:
function search(
items: T[],
query: string,
by?: (it: T) => string,
options?: {
caseSensitive: boolean,
mode: 'word' | 'prefix' | 'autocomplete',
},
): T[]
items is a list of items to search. Typically items will be an array of strings or an array of objects with some string property.query is a string query with which to search the list of items.by (optional) is a predicate function that takes an item from items and returns a string value by which to search for that item. For example, if items is a list of objects like { name: 'Linus' }, by will need to be a function x => x.name. This has the value x => String(x) by default, which works for an items of type string[].options (optional) is a dictionary of options:caseSensitive makes a search case-sensitive. It's false by default.mode controls the way in which incomplete query words are matched:mode: 'word' requires every query word to match only full, exact words rather than parts of words. For example, the query "California" will match "University of California" but not "Californian University".mode: 'prefix' means that every query word may be an incomplete "prefix" of the matched word. "Uni Cali" will match both "University of California" and "Californian University" Even in this mode, every query word must match somewhere — "California" is not a match, because it doesn't match the query word "Uni".mode: 'autocomplete' is a hybrid of the other two modes that's useful when used in autocomplete-style searches, where a user is continuously typing in a query as search results are being returned. This mode is identical to mode: 'word', except that the last query word may be incomplete like in mode: 'prefix'. It means "University of Cali" will match "University of California", which is useful because the user may find their match before having typed in their full query.You can find more examples of how these options combine together in the unit tests.
This will expose the `search` function as `window.libsearch.search`.
### Via NPM
```sh
npm install libsearch
# or
yarn add libsearch
And use in your code:
import { search } from 'libsearch';
// search(...);
…
js
(# matches) / (# words in the doc) * log(# total docs / # docs that matched)
Getting the number of words in a doc requires tokenizing the document, or at least splitting the document by whitespaces, which is computationally expensive. So libsearch approximates this by using the length of the document (number of characters) instead.
Using the regular expression queries described above, libsearch's TF-IDF formula is:
(# RegExp matches) / (doc.length) * log(# docs / # docs that matched RegExp)
…
sh
yarn fmt && yarn build:all && yarn test && yarn docs
to make sure I haven't forgotten anything.
暂无开放 Issues,或尚未同步最近议题。