FlexSearch
Next-Generation full text search library for Browser and Node.js
README
Web's fastest and most memory-flexible full-text search library with zero dependencies.
Basic Start • API Reference • Document Indexes • Using Worker • ChangelogFlexSearch v0.7.0
https://github.com/nextapps-de/flexsearch/blob/master/doc/0.7.0.md
https://github.com/nextapps-de/flexsearch/blob/master/doc/0.7.0-lang.md
Get Latest Stable Build (Recommended)
Build | File | CDN |
flexsearch.bundle.js | Download | https://rawcdn.githack.com/nextapps-de/flexsearch/0.7.31/dist/flexsearch.bundle.js |
flexsearch.light.js | Download | https://rawcdn.githack.com/nextapps-de/flexsearch/0.7.31/dist/flexsearch.light.js |
flexsearch.compact.js | Download | https://rawcdn.githack.com/nextapps-de/flexsearch/0.7.31/dist/flexsearch.compact.js |
flexsearch.es5.js * | Download | https://rawcdn.githack.com/nextapps-de/flexsearch/0.7.31/dist/flexsearch.es5.js |
ES6 Modules | Download | The /dist/module/ folder of this Github repository |
Get Latest (NPM)
- ```cmd
- npm install flexsearch
- ```
Get Latest Nightly (Do not use for production!)
Compare Web-Bundles
The Node.js package includes all features from flexsearch.bundle.js.
Feature | flexsearch.bundle.js | flexsearch.compact.js | flexsearch.light.js |
Presets | ✓ | ✓ | - |
Async Search | ✓ | ✓ | - |
Workers (Web + Node.js) | ✓ | - | - |
Contextual Indexes | ✓ | ✓ | ✓ |
Index Documents (Field-Search) | ✓ | ✓ | - |
Document Store | ✓ | ✓ | - |
Partial Matching | ✓ | ✓ | ✓ |
Relevance Scoring | ✓ | ✓ | ✓ |
Auto-Balanced Cache by Popularity | ✓ | - | - |
Tags | ✓ | - | - |
Suggestions | ✓ | ✓ | - |
Phonetic Matching | ✓ | ✓ | - |
Customizable Charset/Language (Matcher, Encoder, Tokenizer, Stemmer, Filter, Split, RTL) | ✓ | ✓ | ✓ |
Export / Import Indexes | ✓ | - | - |
File Size (gzip) | 6.8 kb | 5.3 kb | 2.9 kb |
Performance Benchmark (Ranking)
Rank | Library | Memory | Query (Single Term) | Query (Multi Term) | Query (Long) | Query (Dupes) | Query (Not Found) |
1 | FlexSearch | 17 | 7084129 | 1586856 | 511585 | 2017142 | 3202006 |
2 | JSii | 27 | 6564 | 158149 | 61290 | 95098 | 534109 |
3 | Wade | 424 | 20471 | 78780 | 16693 | 225824 | 213754 |
4 | JS Search | 193 | 8221 | 64034 | 10377 | 95830 | 167605 |
5 | Elasticlunr.js | 646 | 5412 | 7573 | 2865 | 23786 | 13982 |
6 | BulkSearch | 1021 | 3069 | 3141 | 3333 | 3265 | 21825569 |
7 | MiniSearch | 24348 | 4406 | 10945 | 72 | 39989 | 17624 |
8 | bm25 | 15719 | 1429 | 789 | 366 | 884 | 1823 |
9 | Lunr.js | 2219 | 255 | 271 | 272 | 266 | 267 |
10 | FuzzySearch | 157373 | 53 | 38 | 15 | 32 | 43 |
11 | Fuse | 7641904 | 6 | 2 | 1 | 2 | 3 |
Contextual Search
__Note:__ This feature is disabled by default because of its extended memory usage. Read <a href="#contextual_enable">here</a> get more information about and how to enable.
Load Library
ES6 Modules (Browser):
- ``` js
- import Index from "./index.js";
- import Document from "./document.js";
- import WorkerIndex from "./worker/index.js";
- const index = new Index(options);
- const document = new Document(options);
- const worker = new WorkerIndex(options);
- ```
Bundle (Browser)
- ``` html
- <html>
- <head>
- <script src="js/flexsearch.bundle.js"></script>
- </head>
- ...
- ```
- ``` html
- <script src="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@0.7.31/dist/flexsearch.bundle.js"></script>
- ```
- ``` js
- var FlexSearch = require("./flexsearch.js");
- ```
- ``` js
- var index = new FlexSearch.Index(options);
- var document = new FlexSearch.Document(options);
- var worker = new FlexSearch.Worker(options);
- ```
Node.js
- ```npm
- npm install flexsearch
- ```
- ``` js
- const { Index, Document, Worker } = require("flexsearch");
- const index = new Index(options);
- const document = new Document(options);
- const worker = new Worker(options);
- ```
Basic Usage and Variants
- ``` js
- index.add(id, text);
- index.search(text);
- index.search(text, limit);
- index.search(text, options);
- index.search(text, limit, options);
- index.search(options);
- ```
- ``` js
- document.add(doc);
- document.add(id, doc);
- document.search(text);
- document.search(text, limit);
- document.search(text, options);
- document.search(text, limit, options);
- document.search(options);
- ```
- ``` js
- worker.add(id, text);
- worker.search(text);
- worker.search(text, limit);
- worker.search(text, options);
- worker.search(text, limit, options);
- worker.search(text, limit, options, callback);
- worker.search(options);
- ```
Every method called on a Worker index is treated as async. You will get back a Promise or you can provide a callback function as the last parameter alternatively.
API Overview
Options
Index Options
Option | Values | Description | Default |
preset | "memory" "performance" "match" "score" "default" | The configuration profile as a shortcut or as a base for your custom settings. | "default" |
tokenize | "strict" "forward" "reverse" "full" | The indexing mode (tokenizer). Choose one of the built-ins or pass a custom tokenizer function. | "strict" |
cache | Boolean Number | Enable/Disable and/or set capacity of cached entries. When passing a number as a limit the cache automatically balance stored entries related to their popularity. Note: When just using "true" the cache has no limits and growth unbounded. | false |
resolution | Number | Sets the scoring resolution (default: 9). | 9 |
context | Boolean Context Options | Enable/Disable contextual indexing. When passing "true" as value it will take the default values for the context. | false |
optimize | Boolean | When enabled it uses a memory-optimized stack flow for the index. | true |
boost | function(arr, str, int) => float | A custom boost function used when indexing contents to the index. The function has this signature: Function(words[], term, index) => Float . It has 3 parameters where you get an array of all words, the current term and the current index where the term is placed in the word array. You can apply your own calculation e.g. the occurrences of a term and return this factor (<1 means relevance is lowered, >1 means relevance is increased).Note: this feature is currently limited by using the tokenizer "strict" only. | null |
Language-specific Options and Encoding: | |||
charset | Charset Payload String (key) | Provide a custom charset payload or pass one of the keys of built-in charsets. | "latin" |
language | Language Payload String (key) | Provide a custom language payload or pass in language shorthand flag (ISO-3166) of built-in languages. | null |
encode | false "default" "simple" "balance" "advanced" "extra" function(str) => [words] | The encoding type. Choose one of the built-ins or pass a custom encoding function. | "default" |
stemmer | false String Function | false | |
filter | false String Function | false | |
matcher | false String Function | false | |
Additional Options for Document Indexes: | |||
worker | Boolean | Enable/Disable and set count of running worker threads. | false |
document | Document Descriptor | Includes definitions for the document index and storage. |
Context Options
Option | Values | Description | Default |
resolution | Number | Sets the scoring resolution for the context (default: 1). | 1 |
depth | false Number | Enable/Disable contextual indexing and also sets contextual distance of relevance. Depth is the maximum number of words/tokens away a term to be considered as relevant. | 1 |
bidirectional | Boolean | Sets the scoring resolution (default: 9). | true |
Document Options
Option | Values | Description | Default |
id | String | "id"" | |
tag | false String | "tag" | |
index | String Array<String> Array<Object> | ||
store | Boolean String Array<String> | false |
Charset Options
Option | Values | Description | Default |
split | false RegExp String | The rule to split words when using non-custom tokenizer (built-ins e.g. "forward"). Use a string/char or use a regular expression (default: /\W+/ ). | /[\W_]+/ |
rtl | Boolean | Enables Right-To-Left encoding. | false |
encode | function(str) => [words] | The custom encoding function. | /lang/latin/default.js |
Language Options
Option | Values | Description |
stemmer | false String Function | Disable or pass in language shorthand flag (ISO-3166) or a custom object. |
filter | false String Function | Disable or pass in language shorthand flag (ISO-3166) or a custom array. |
matcher | false String Function | Disable or pass in language shorthand flag (ISO-3166) or a custom array. |
Search Options
Option | Values | Description | Default |
limit | number | Sets the limit of results. | 100 |
offset | number | Apply offset (skip items). | 0 |
suggest | Boolean | Enables suggestions in results. | false |
Document Search Options
Option | Values | Description | Default |
index | String Array<String> Array<Object> | Sets the document fields which should be searched. When no field is set, all fields will be searched. Custom options per field are also supported. | |
tag | String Array<String> | Sets the document fields which should be searched. When no field is set, all fields will be searched. Custom options per field are also supported. | false |
enrich | Boolean | Enrich IDs from the results with the corresponding documents. | false |
bool | "and" "or" | Sets the used logical operator when searching through multiple fields or tags. | "or" |
Tokenizer (Prefix Search)
Option | Description | Example | Memory Factor (n = length of word) |
"strict" | index whole words | foobar | * 1 |
"forward" | incrementally index words in forward direction | fo obarfoob ar | * n |
"reverse" | incrementally index words in both directions | foobar fo obar | * 2n - 1 |
"full" | index every possible combination | fooba rf oob ar | * n * (n - 1) |
Encoders
Option | Description | False-Positives | Compression |
false | Turn off encoding | no | 0% |
"default" | Case in-sensitive encoding | no | 0% |
"simple" | Case in-sensitive encoding Charset normalizations | no | ~ 3% |
"balance" | Case in-sensitive encoding Charset normalizations Literal transformations | no | ~ 30% |
"advanced" | Case in-sensitive encoding Charset normalizations Literal transformations Phonetic normalizations | no | ~ 40% |
"extra" | Case in-sensitive encoding Charset normalizations Literal transformations Phonetic normalizations Soundex transformations | yes | ~ 65% |
function() | Pass custom encoding via function(string):[words] |
Usage
Create a new index
- ``` js
- var index = new Index();
- ```
- ``` js
- var index = new Index("performance");
- ```
- ``` js
- var index = new Index({
- charset: "latin:extra",
- tokenize: "reverse",
- resolution: 9
- });
- ```
- ``` js
- var index = new FlexSearch({
- preset: "memory",
- tokenize: "forward",
- resolution: 5
- });
- ```
Add text item to an index
Index.__add(id, string)__
- ``` js
- index.add(0, "John Doe");
- ```
Search items
Index.__search(string | options, \<limit\>, \<options\>)__
- ``` js
- index.search("John");
- ```
- ``` js
- index.search("John", 10);
- ```
Check existence of already indexed IDs
- ``` js
- if(index.contain(1)){
- console.log("ID is already in index");
- }
- ```
Async
- ``` js
- index.addAsync(id, content, function(){
- console.log("Task Done");
- });
- index.searchAsync(query, function(result){
- console.log("Results: ", result);
- });
- ```
- ``` js
- index.addAsync(id, content).then(function(){
- console.log("Task Done");
- });
- index.searchAsync(query).then(function(result){
- console.log("Results: ", result);
- });
- ```
- ``` js
- async function add(){
- await index.addAsync(id, content);
- console.log("Task Done");
- }
- async function search(){
- const results = await index.searchAsync(query);
- console.log("Results: ", result);
- }
- ```
Append Contents
- ``` js
- index.append(id, content);
- ```
- ``` js
- index.add(0, "some index");
- index.append(0, "some appended content");
- index.add(1, "some text");
- index.append(1, "index appended content");
- ```
Update item from an index
Index.__update(id, string)__
- ``` js
- index.update(0, "Max Miller");
- ```
Remove item from an index
Index.__remove(id)__
- ``` js
- index.remove(0);
- ```
Add custom tokenizer
A tokenizer split words/terms into components or partials.
- ``` js
- var index = new FlexSearch({
- tokenize: function(str){
- return str.split(/\s-\//g);
- }
- });
- ```
The tokenizer function gets a string as a parameter and has to return an array of strings representing a word or term. In some languages every char is a term and also not separated via whitespaces.
Add language-specific stemmer and/or filter
__Stemmer:__ several linguistic mutations of the same word (e.g. "run" and "running")
__Filter:__ a blacklist of words to be filtered out from indexing at all (e.g. "and", "to" or "be")
- ``` js
- var index = new FlexSearch({
- stemmer: {
- // object {key: replacement}
- "ational": "ate",
- "tional": "tion",
- "enci": "ence",
- "ing": ""
- },
- filter: [
- // array blacklist
- "in",
- "into",
- "is",
- "isn't",
- "it",
- "it's"
- ]
- });
- ```
- ``` js
- var index = new FlexSearch({
- filter: function(value){
- // just add values with length > 1 to the index
- return value.length > 1;
- }
- });
- ```
Stemmer are passed as a object (key-value-pair), filter as an array.
- ``` js
- FlexSearch.registerLanguage("us", {
- stemmer: { /* ... */ },
- filter: [ /* ... */ ]
- });
- ```
- ``` html
- <html>
- <head>
- <script src="js/flexsearch.bundle.js"></script>
- <script src="js/lang/en.min.js"></script>
- <script src="js/lang/de.min.js"></script>
- </head>
- ...
- ```
- ``` js
- var index_en = new FlexSearch.Index({
- language: "en"
- });
- var index_de = new FlexSearch.Index({
- language: "de"
- });
- ```
- ``` js
- const { Index } = require("flexsearch");
- var index_en = new Index({
- language: "en"
- });
- ```
Right-To-Left Support
Set the tokenizer at least to "reverse" or "full" when using RTL.
- ``` js
- var index = new Index({
- encode: str => str.toLowerCase().split(/[^a-z]+/),
- tokenize: "reverse",
- rtl: true
- });
- ```
CJK Word Break (Chinese, Japanese, Korean)
- ``` js
- var index = FlexSearch.create({
- encode: str => str.replace(/[\x00-\x7F]/g, "").split("")
- });
- ```
- ``` js
- index.add(0, "一个单词");
- ```
- ``` js
- var results = index.search("单词");
- ```
Index Documents (Field-Search)
The Document Descriptor
- ``` json
- {
- "id": 0,
- "content": "some text"
- }
- ```
- ``` js
- const index = new Document({
- doc: {
- id: "id",
- field: ["content"]
- }
- });
- ```
The document descriptor has slightly changed, there is no field branch anymore, instead just apply one level higher, so key becomes a main member of options.
- ``` js
- const index = new Document({
- document: {
- id: "id",
- index: ["content"]
- }
- });
- index.add({
- id: 0,
- content: "some text"
- });
- ```
- ``` js
- const index = new Document({
- document: {
- index: ["content"]
- }
- });
- ```
- ``` js
- const index = new Document({ document: "content" });
- index.add({ id: 0, content: "some text" });
- ```
- ``` js
- var docs = [{
- id: 0,
- title: "Title A",
- content: "Body A"
- },{
- id: 1,
- title: "Title B",
- content: "Body B"
- }];
- ```
- ``` js
- const index = new Document({
- id: "id",
- index: ["title", "content"]
- });
- ```
- ``` js
- const index = new Document({
- id: "id",
- index: [{
- field: "title",
- tokenize: "forward",
- optimize: true,
- resolution: 9
- },{
- field: "content",
- tokenize: "strict",
- optimize: true,
- resolution: 5,
- minlength: 3,
- context: {
- depth: 1,
- resolution: 3
- }
- }]
- });
- ```
- ``` js
- const index = new Document({
- tokenize: "strict",
- optimize: true,
- resolution: 9,
- document: {
- id: "id",
- index:[{
- field: "title",
- tokenize: "forward"
- },{
- field: "content",
- minlength: 3,
- context: {
- depth: 1,
- resolution: 3
- }
- }]
- }
- });
- ```
Nested Data Fields (Complex Objects)
- ``` json
- {
- "record": {
- "id": 0,
- "title": "some title",
- "content": {
- "header": "some text",
- "footer": "some text"
- }
- }
- }
- ```
- ``` js
- const index = new Document({
- document: {
- id: "record:id",
- index: [
- "record:title",
- "record:content:header",
- "record:content:footer"
- ]
- }
- });
- ```
Just add fields you want to query against. Do not add fields to the index, you just need in the result (but did not query against). For this purpose you can store documents independently of its index (read below).
- ``` js
- index.search(query, {
- index: [
- "record:title",
- "record:content:header",
- "record:content:footer"
- ]
- });
- ```
- ``` js
- index.search(query, [
- "record:title",
- "record:content:header",
- "record:content:footer"
- ]);
- ```
- ``` js
- index.search([{
- field: "record:title",
- query: "some query",
- limit: 100,
- suggest: true
- },{
- field: "record:title",
- query: "some other query",
- limit: 100,
- suggest: true
- }]);
- ```
When passing field-specific options you need to provide the full configuration for each field. They get not inherited like the document descriptor.
Complex Documents
- ``` js
- [ // <-- not allowed as document start!
- {
- "id": 0,
- "title": "title"
- }
- ]
- ```
- ``` js
- {
- "records": [ // <-- not allowed when ID or tag lives inside!
- {
- "id": 0,
- "title": "title"
- }
- ]
- }
- ```
- ``` json
- {
- "meta": {
- "tag": "cat",
- "id": 0
- },
- "contents": [
- {
- "body": {
- "title": "some title",
- "footer": "some text"
- },
- "keywords": ["some", "key", "words"]
- },
- {
- "body": {
- "title": "some title",
- "footer": "some text"
- },
- "keywords": ["some", "key", "words"]
- }
- ]
- }
- ```
- ``` js
- const index = new Document({
- document: {
- id: "meta:id",
- tag: "meta:tag",
- index: [
- "contents[]:body:title",
- "contents[]:body:footer",
- "contents[]:keywords"
- ]
- }
- });
- ```
- ``` js
- index.search(query, {
- index: "contents[]:body:title"
- });
- ```
Not Supported Documents (Sequential Data)
- ``` js
- [ // <-- not allowed as document start!
- {
- "tag": "cat",
- "records": [ // <-- not allowed when ID or tag lives inside!
- {
- "id": 0,
- "body": {
- "title": "some title",
- "footer": "some text"
- },
- "keywords": ["some", "key", "words"]
- },
- {
- "id": 1,
- "body": {
- "title": "some title",
- "footer": "some text"
- },
- "keywords": ["some", "key", "words"]
- }
- ]
- }
- ]
- ```
- ``` js
- const index = new Document({
- document: {
- id: "record:id",
- tag: "tag",
- index: [
- "record:body:title",
- "record:body:footer",
- "record:body:keywords"
- ]
- }
- });
- function add(sequential_data){
- for(let x = 0, data; x < sequential_data.length; x++){
- data = sequential_data[x];
- for(let y = 0, record; y < data.records.length; y++){
- record = data.records[y];
- index.add({
- id: record.id,
- tag: data.tag,
- record: record
- });
- }
- }
- }
- // now just use add() helper method as usual:
- add([{
- // sequential structured data
- // take the data example above
- }]);
- ```
Add/Update/Remove Documents to/from the Index
- ``` js
- index.add(docs);
- ```
- ``` js
- index.update({
- data:{
- id: 0,
- title: "Foo",
- body: {
- content: "Bar"
- }
- }
- });
- ```
- ``` js
- index.remove(docs);
- ```
- ``` js
- index.remove(id);
- ```
Join / Append Arrays
Field-Search
- ``` js
- index.search(query);
- ```
- ``` js
- index.search(query, { index: "title" });
- ```
- ``` js
- index.search(query, { index: ["title", "content"] });
- ```
- ``` js
- index.search(query, ["title", "content"]);
- ```
- ``` js
- index.search([{
- field: "content",
- query: "some query",
- limit: 100,
- suggest: true
- },{
- field: "content",
- query: "some other query",
- limit: 100,
- suggest: true
- }]);
- ```
The Result Set
fields[] => { field, result[] => { document }}
- ``` js
- [{
- field: "title",
- result: [0, 1, 2]
- },{
- field: "content",
- result: [3, 4, 5]
- }]
- ```
- ``` js
- [{
- field: "title",
- result: [
- { id: 0, doc: { /* document */ }},
- { id: 1, doc: { /* document */ }},
- { id: 2, doc: { /* document */ }}
- ]
- },{
- field: "content",
- result: [
- { id: 3, doc: { /* document */ }},
- { id: 4, doc: { /* document */ }},
- { id: 5, doc: { /* document */ }}
- ]
- }]
- ```
- ``` js
- index.search(query, { pluck: "title", enrich: true });
- ```
- ``` js
- [
- { id: 0, doc: { /* document */ }},
- { id: 1, doc: { /* document */ }},
- { id: 2, doc: { /* document */ }}
- ]
- ```
A field search will apply a query with the boolean "or" logic by default. Each field has its own result to the given query.
- ``` js
- index.search(query, {
- index: ["title", "content"],
- bool: "and"
- });
- ```
Tags
- ``` js
- const index = new Document({
- document: {
- id: "id",
- tag: "tag",
- index: "content"
- }
- });
- ```
- ``` js
- index.add({
- id: 0,
- tag: "cat",
- content: "Some content ..."
- });
- ```
- ``` js
- index.add({
- id: 1,
- tag: ["animal", "dog"],
- content: "Some content ..."
- });
- ```
- ``` js
- index.search(query, {
- index: "content",
- tag: "animal"
- });
- ```
- ``` js
- index.search(query, {
- index: "content",
- tag: ["cat", "dog"]
- });
- ```
Multiple tags will apply as the boolean "or" by default. It just needs one of the tags to be existing.
- ``` js
- index.search(query, {
- index: "content",
- tag: ["dog", "animal"],
- bool: "and"
- });
- ```
Tag Search
- ``` js
- index.search({ tag: ["cat", "dog"] });
- ```
- ``` js
- [{
- tag: "cat",
- result: [ /* all cats */ ]
- },{
- tag: "dog",
- result: [ /* all dogs */ ]
- }]
- ```
Limit & Offset
By default, every query is limited to 100 entries. Unbounded queries leads into issues. You need to set the limit as an option to adjust the size.
- ``` js
- index.search(query, { limit: 20, offset: 100 });
- ```
You cannot pre-count the size of the result-set. That's a limit by the design of FlexSearch. When you really need a count of all results you are able to page through, then just assign a high enough limit and get back all results and apply your paging offset manually (this works also on server-side). FlexSearch is fast enough that this isn't an issue.
Document Store
Do not use a store when: 1. an array of IDs as the result is good enough, or 2. you already have the contents/documents stored elsewhere (outside the index).
When the store attribute was set, you have to include all fields which should be stored explicitly (acts like a whitelist).
When the store attribute was not set, the original document is stored as a fallback.
- ``` js
- const index = new Document({
- document: {
- index: "content",
- store: true
- }
- });
- index.add({ id: 0, content: "some text" });
- ```
Access documents from internal store
- ``` js
- var data = index.get(1);
- ```
- ``` js
- index.set(1, data);
- ```
- ``` js
- index.search(query, { enrich: true });
- ```
- ``` js
- [{
- id: 0,
- doc: { /* content from store */ }
- },{
- id: 1,
- doc: { /* content from store */ }
- }]
- ```
Configure Storage (Recommended)
- ``` js
- const index = new Document({
- document: {
- index: "content",
- store: ["author", "email"]
- }
- });
- index.add(id, content);
- ```
- ``` js
- const index = new Document({
- document: {
- index: "content",
- store: ["author", "email"]
- }
- });
- index.add({
- id: 0,
- author: "Jon Doe",
- email: "john@mail.com",
- content: "Some content for the index ..."
- });
- ```
- ``` js
- index.search("some content", { enrich: true });
- ```
- ``` js
- [{
- field: "content",
- result: [{
- id: 0,
- doc: {
- author: "Jon Doe",
- email: "john@mail.com",
- }
- }]
- }]
- ```
Chaining
- ``` js
- var index = FlexSearch.create()
- .addMatcher({'â': 'a'})
- .add(0, 'foo')
- .add(1, 'bar');
- ```
- ``` js
- index.remove(0).update(1, 'foo').add(2, 'foobar');
- ```
Enable Contextual Scoring
- ``` js
- var index = new FlexSearch({
- tokenize: "strict",
- context: true
- });
- ```
- ``` js
- var index = new FlexSearch({
- tokenize: "strict",
- context: {
- resolution: 5,
- depth: 3,
- bidirectional: true
- }
- });
- ```
Only the tokenizer "strict" is actually supported by the contextual index.
The contextual index requires <a href="#memory">additional amount of memory</a> depending on depth.
Auto-Balanced Cache (By Popularity)
- ``` js
- const index = new Index({ cache: 100 });
- ```
- ``` js
- const results = index.searchCache(query);
- ```
When passing a number as a limit the cache automatically balance stored entries related to their popularity.
When just using "true" the cache is unbounded and perform actually 2-3 times faster (because the balancer do not have to run).
Worker Parallelism (Browser + Node.js)
- ``` js
- const index = new Document({
- index: ["tag", "name", "title", "text"],
- worker: true
- });
- index.add({
- id: 1, tag: "cat", name: "Tom", title: "some", text: "some"
- }).add({
- id: 2, tag: "dog", name: "Ben", title: "title", text: "content"
- }).add({
- id: 3, tag: "cat", name: "Max", title: "to", text: "to"
- }).add({
- id: 4, tag: "dog", name: "Tim", title: "index", text: "index"
- });
- ```
- ```
- Worker 1: { 1: "cat", 2: "dog", 3: "cat", 4: "dog" }
- Worker 2: { 1: "Tom", 2: "Ben", 3: "Max", 4: "Tim" }
- Worker 3: { 1: "some", 2: "title", 3: "to", 4: "index" }
- Worker 4: { 1: "some", 2: "content", 3: "to", 4: "index" }
- ```
Worker Index
- ``` js
- import WorkerIndex from "./worker/i