From c9adfc12ae939e51363a4071ea0fed6f9abebe66 Mon Sep 17 00:00:00 2001 From: Thomas Wilkerling Date: Tue, 20 Mar 2018 21:58:42 +0100 Subject: [PATCH] ADD profiles --- README.md | 84 +++++++--- flexsearch.js | 172 ++++++++++++++------ flexsearch.light.js | 26 +-- flexsearch.min.js | 49 +++--- package.json | 2 +- test/matching-flexsearch.html | 290 ++++++++++++++++++++++++++++++++++ test/matching.html | 35 ++-- test/test.js | 21 +-- 8 files changed, 550 insertions(+), 129 deletions(-) create mode 100644 test/matching-flexsearch.html diff --git a/README.md b/README.md index 34d77d6..a848380 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,13 @@ When it comes to raw search speed FlexSearch outperforms every single searching library out there and also provides flexible search capabilities like multi-word matching, phonetic transformations or partial matching. It also has the __most memory-efficient index__. Keep in mind that updating / removing existing items from the index has a significant cost. When your index needs to be updated continuously then BulkSearch may be a better choice. -FlexSearch also provides you a non-blocking asynchronous processing model as well as web workers to perform any updates on the index as well as queries through dedicated threads. +FlexSearch also provides you a non-blocking asynchronous processing model as well as web workers to perform any updates or queries on the index in parallel through dedicated balanced threads. -Installation Guide  •  API Reference  •  Example Options  •  Custom Builds +Installation Guide  •  API Reference  •  Example Options  •  Custom Builds Comparison: - Library Benchmarks -- BulkSearch vs. FlexSearch Benchmark -- Relevance Scoring +- Library Relevance Scoring Supported Platforms: - Browser @@ -42,14 +41,14 @@ All Features:
  • Multiple Words
  • Phonetic Search
  • Relevance-based Scoring
  • -
  • Contextual Indexes
  • +
  • Contextual Indexes
  • Limit Results
  • Supports Caching
  • Asynchronous Processing
  • Customizable: Matcher, Encoder, Tokenizer, Stemmer, Stopword-Filter
  • -This features are not available in the 50% smaller light version: +These features are not available in the 50% smaller light version: - WebWorker - Async handler @@ -216,6 +215,12 @@ alternatively you can also use: var index = FlexSearch.create(); ``` +##### Create a new index and choosing one of the built-in profiles + +```js +var index = new FlexSearch("speed"); +``` + ##### Create a new index with custom options ```js @@ -223,6 +228,7 @@ var index = new FlexSearch({ // default values: + profile: "balance", encode: "icase", mode: "ngram", async: false, @@ -230,7 +236,8 @@ var index = new FlexSearch({ }); ``` -__Read more:__ Phonetic Search, Phonetic Comparison, Improve Memory Usage +Read more about custom options + #### Add items to an index @@ -488,7 +495,7 @@ index.search("John Doe", function(results){ ## Options -FlexSearch ist highly customizable. Make use of the the right options can really improve your results as well as memory economy or query time. +FlexSearch ist highly customizable. Make use of the the right options can really improve your results as well as memory economy or query time. @@ -498,7 +505,22 @@ FlexSearch ist highly customizable. Make use of the the right options can really - + + + + + + +
    Description
    mode




    profile





    + "memory"
    + "speed"
    + "match"
    + "score"
    + "balance"
    + "fastest" +
    + The configuration profile.
    +
    mode





    "strict"
    "foward"
    @@ -872,31 +894,32 @@ The required memory for the index depends on several options:
    - -## Example Options + +## Built-in Profiles -Memory-optimized: +You can pass a built-in profile during creation/initialization. They have these following settings: +Memory-optimized profile: __"memory"__ ```js { encode: "extra", mode: "strict", - threshold: 5 + threshold: 7 } ``` -Speed-optimized: +Speed-optimized profile: __"speed"__ ```js { encode: "icase", mode: "strict", - threshold: 5, + threshold: 7, depth: 2 } ``` -Matching-tolerant: +Matching-tolerant profile: __"match"__ ```js { @@ -905,17 +928,42 @@ Matching-tolerant: } ``` -Well-balanced: +Relevance-optimized profile: __"score"__ ```js { encode: "extra", + mode: "strict", + threshold: 5, + depth: 4 +} +``` + +Most-balanced profile: __"balanced"__ + +```js +{ + encode: "balanced", mode: "ngram", - threshold: 4, + threshold: 6, depth: 3 } ``` +Absolute fastest profile: __"fastest"__ + +```js +{ + encode: "icase", + threshold: 9, + depth: 1 +} +``` + +Compare these options above: +- Benchmarks +- Relevance Scoring + ## Custom Builds diff --git a/flexsearch.js b/flexsearch.js index f58bac2..e875e1d 100644 --- a/flexsearch.js +++ b/flexsearch.js @@ -1,5 +1,5 @@ ;/**! - * @preserve FlexSearch v0.2.3 + * @preserve FlexSearch v0.2.32 * Copyright 2017-2018 Thomas Wilkerling * Released under the Apache 2.0 Licence * https://github.com/nextapps-de/flexsearch @@ -35,8 +35,9 @@ var SUPPORT_ASYNC = true; var defaults = { - // bitsize of assigned IDs (data type) - type: 'integer', + // use on of built-in functions + // or pass custom encoding algorithm + encode: 'icase', // type of information mode: 'forward', @@ -54,11 +55,55 @@ var SUPPORT_ASYNC = true; threshold: 0, // contextual depth - depth: 0, + depth: 0 + }; - // use on of built-in functions - // or pass custom encoding algorithm - encode: 'icase' + /** + * @struct + * @private + * @const + * @final + */ + + var profiles = { + + "memory": { + encode: "extra", + mode: "strict", + threshold: 7 + }, + + "speed": { + encode: "icase", + mode: "strict", + threshold: 7, + depth: 2 + }, + + "match": { + encode: "extra", + mode: "full" + }, + + "score": { + encode: "extra", + mode: "strict", + threshold: 5, + depth: 4 + }, + + "balance": { + encode: "balance", + mode: "ngram", + threshold: 6, + depth: 3 + }, + + "fastest": { + encode: "icase", + threshold: 9, + depth: 1 + } }; /** @@ -94,7 +139,7 @@ var SUPPORT_ASYNC = true; * @const {Array} */ - var filter = SUPPORT_BUILTINS ? [ + var filter = [ "a", "about", @@ -301,14 +346,13 @@ var SUPPORT_ASYNC = true; "yourself", "yourselves", "you've" - - ] : null; + ]; /** * @const {Object} */ - var stemmer = SUPPORT_BUILTINS ? { + var stemmer = { "ational": "ate", "tional": "tion", @@ -356,18 +400,24 @@ var SUPPORT_ASYNC = true; "ous": "", "ive": "", "ize": "" - - } : null; + }; /** - * @param {Object=} options + * @param {string|Object=} options * @constructor * @private */ function FlexSearch(options){ - options || (options = defaults); + if(typeof options === 'string'){ + + options = profiles[options] || defaults; + } + else{ + + options || (options = defaults); + } // generate UID @@ -467,9 +517,11 @@ var SUPPORT_ASYNC = true; if(options){ + var custom; + // initialize worker - if(SUPPORT_WORKER && options['worker']){ + if(SUPPORT_WORKER && (custom = options['worker'])){ if(typeof Worker === 'undefined'){ @@ -485,7 +537,7 @@ var SUPPORT_ASYNC = true; else{ var self = this; - var threads = parseInt(options['worker'], 10) || 4; + var threads = parseInt(custom, 10) || 4; self._current_task = -1; self._task_completed = 0; @@ -536,7 +588,30 @@ var SUPPORT_ASYNC = true; } } - // apply options + // apply profile options + + if((custom = options['profile'])) { + + this.profile = custom || 'custom'; + + custom = profiles[custom]; + + if(custom) { + + for(var option in custom){ + + if(custom.hasOwnProperty(option)){ + + if(typeof options[option] === 'undefined'){ + + options[option] = custom[option]; + } + } + } + } + } + + // apply custom options this.mode = ( @@ -580,10 +655,12 @@ var SUPPORT_ASYNC = true; defaults.depth ); + custom = options['encode']; + this.encoder = ( - (options['encode'] && global_encoder[options['encode']]) || - (typeof options['encode'] === 'function' ? options['encode'] : this.encoder || false) + (custom && global_encoder[custom]) || + (typeof custom === 'function' ? custom : this.encoder || false) ); if(SUPPORT_DEBUG){ @@ -595,35 +672,35 @@ var SUPPORT_ASYNC = true; ); } - if(options['matcher']) { + if(custom = options['matcher']) { - this.addMatcher(/** @type {Object} */ (options['matcher'])); + this.addMatcher(/** @type {Object} */ (custom)); } - if(options['filter']) { + if(SUPPORT_BUILTINS && (custom = options['filter'])) { this.filter = initFilter( - (options['filter'] === true ? + (custom === true ? filter : - /** @type {Array} */ (options['filter']) + /** @type {Array} */ (custom) - ), this.encoder); + ), this.encoder); } - if(options['stemmer']) { + if(SUPPORT_BUILTINS && (custom = options['stemmer'])) { this.stemmer = initStemmer( - (options['stemmer'] === true ? + (custom === true ? stemmer : - /** @type {Object} */ (options['stemmer']) + /** @type {Object} */ (custom) - ), this.encoder); + ), this.encoder); } } @@ -932,7 +1009,7 @@ var SUPPORT_ASYNC = true; threshold ); - if(depth && (word_length > 1) && (score > threshold)){ + if(depth && (word_length > 1) && (score >= threshold)){ var ctx_map = map[10]; var ctx_dupes = dupes['_ctx'][value] || (dupes['_ctx'][value] = {}); @@ -1476,7 +1553,7 @@ var SUPPORT_ASYNC = true; /** @const */ - var global_encoder_balanced = (function(){ + var global_encoder_balance = (function(){ var regex_whitespace = regex('\\s\\s+'), regex_strip = regex('[^a-z0-9 ]'), @@ -1702,16 +1779,7 @@ var SUPPORT_ASYNC = true; }; })(), - 'balanced': global_encoder_balanced - - // TODO: provide some common encoder plugins - // soundex - // cologne - // metaphone - // caverphone - // levinshtein - // hamming - // matchrating + 'balance': global_encoder_balance } : { @@ -1722,7 +1790,7 @@ var SUPPORT_ASYNC = true; return value.toLowerCase(); }, - 'balanced': global_encoder_balanced + 'balance': global_encoder_balance }; // Xone Async Handler Fallback @@ -1846,7 +1914,7 @@ var SUPPORT_ASYNC = true; dupes[tmp] = score; - if(score > threshold){ + if(score >= threshold){ var arr = map[score]; arr = arr[tmp] || (arr[tmp] = []); @@ -2525,13 +2593,17 @@ var SUPPORT_ASYNC = true; URL.createObjectURL( - new Blob( + new Blob([ - ['(' + _worker.toString() + ')()'], { - - 'type': 'text/javascript' - } - ) + 'var SUPPORT_WORKER = true;' + + 'var SUPPORT_BUILTINS = ' + (SUPPORT_BUILTINS ? 'true' : 'false') + ';' + + 'var SUPPORT_DEBUG = ' + (SUPPORT_DEBUG ? 'true' : 'false') + ';' + + 'var SUPPORT_CACHE = ' + (SUPPORT_CACHE ? 'true' : 'false') + ';' + + 'var SUPPORT_ASYNC = ' + (SUPPORT_ASYNC ? 'true' : 'false') + ';' + + '(' + _worker.toString() + ')()' + ],{ + 'type': 'text/javascript' + }) ) : diff --git a/flexsearch.light.js b/flexsearch.light.js index df6b35d..702b23d 100644 --- a/flexsearch.light.js +++ b/flexsearch.light.js @@ -1,18 +1,18 @@ /* - FlexSearch v0.2.3 + FlexSearch v0.2.32 Copyright 2017-2018 Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch */ -'use strict';(function(h,t,l){var q;(q=l.define)&&q.amd?q([],function(){return t}):(q=l.modules)?q[h.toLowerCase()]=t:"undefined"!==typeof module?module.exports=t:l[h]=t})("FlexSearch",function(){function h(a){a||(a=y);this.id=a.id||C++;this.init(a);t(this,"index",function(){return this.a});t(this,"length",function(){return Object.keys(this.a).length})}function t(a,b,c){Object.defineProperty(a,b,{get:c})}function l(a){return new RegExp(a,"g")}function q(a,b,c){if("undefined"===typeof c){for(c=0;c< -b.length;c+=2)a=a.replace(b[c],b[c+1]);return a}return a.replace(b,c)}function w(a,b,c,g,d,e){if("undefined"===typeof b[c]){var f=d.indexOf(c);f=3/d.length*(d.length-f)+6/(f-d.lastIndexOf(" ",f))+.5|0;b[c]=f;f>e&&(a=a[f],a=a[c]||(a[c]=[]),a[a.length]=g)}return f||b[c]}function A(a){var b=[];if(!a)return b;for(var c=0,g=0,d=0,e="",f=a.length,p=0;pa?1:0a?-1:0b&&(c=c.slice(0,b)));return c}var y= -{type:"integer",mode:"forward",cache:!1,async:!1,l:!1,threshold:0,depth:0,encode:"icase"},x=[],C=0,B=l("[ -/]");h.new=function(a){return new this(a)};h.create=function(a){return h.new(a)};h.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(x[x.length]=l(b),x[x.length]=a[b]);return this};h.register=function(a,b){v[a]=b;return this};h.encode=function(a,b){return v[a].call(v,b)};h.prototype.init=function(a){this.c=[];if(a&&(this.mode=a.mode||this.mode||y.mode,this.threshold=a.threshold||this.threshold|| -y.threshold,this.depth=a.depth||this.depth||y.depth,this.h=a.encode&&v[a.encode]||("function"===typeof a.encode?a.encode:this.h||!1),a.matcher&&this.addMatcher(a.matcher),a.filter&&(this.i={}),a.stemmer)){a=!0===a.stemmer?null:a.stemmer;var b=this.h,c=[];if(a){var g=0,d;for(d in a)if(a.hasOwnProperty(d)){var e=b?b.call(v,d):d;c[g++]=l("(?=.{"+(e.length+3)+",})"+e+"$");c[g++]=b?b.call(v,a[d]):a[d]}}this.j=c}this.b=[{},{},{},{},{},{},{},{},{},{},{}];this.a={};this.f="";this.g=!0;return this};h.prototype.encode= -function(a){a&&x.length&&(a=q(a,x));a&&this.c.length&&(a=q(a,this.c));a&&this.h&&(a=this.h.call(v,a));if(a&&this.i){a=a.split(" ");for(var b=0;bk;l--)u=n.substring(k,l),w(p,d,u,a,b,e);break;default:if(k=w(p,d,n,a,b,e),f&&1e)for(k=p[10], -r=d._ctx[n]||(d._ctx[n]={}),n=k[n]||(k[n]=[{},{},{},{},{},{},{},{},{},{}]),k=h-f,l=h+f,0>k&&(k=0),l>m-1&&(l=m-1);k<=l;k++)k!==h&&w(n,r,g[k],a,b,e)}}}this.a[a]="1";this.g=!1}return this};h.prototype.update=function(a,b){"string"===typeof b&&(a||0===a)&&this.a[a]&&(this.remove(a),b&&this.add(a,b));return this};h.prototype.remove=function(a){if(this.a[a]){for(var b=0;10>b;b++)for(var c=Object.keys(this.b[b]),g=0;g=d;z--)if(v=(r?k[u]:this.b)[z][t])w[y++]=v,x=!0;if(x)l[l.length]=1=e&&(a=a[f],a=a[c]||(a[c]=[]),a[a.length]=k)}return f||b[c]}function B(a){var b=[];if(!a)return b;for(var c=0,k=0,g=0,e="",f=a.length,p=0;pa?1:0a?-1:0b&&(c= +c.slice(0,b)));return c}var x={encode:"icase",mode:"forward",cache:!1,async:!1,l:!1,threshold:0,depth:0},A={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5,depth:4},balance:{encode:"balance",mode:"ngram",threshold:6,depth:3},fastest:{encode:"icase",threshold:9,depth:1}},w=[],D=0,C=l("[ -/]");d.new=function(a){return new this(a)};d.create=function(a){return d.new(a)}; +d.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(w[w.length]=l(b),w[w.length]=a[b]);return this};d.register=function(a,b){y[a]=b;return this};d.encode=function(a,b){return y[a].call(y,b)};d.prototype.init=function(a){this.c=[];if(a){var b;if(b=a.profile)if(b=A[b])for(var c in b)b.hasOwnProperty(c)&&"undefined"===typeof a[c]&&(a[c]=b[c]);this.mode=a.mode||this.mode||x.mode;this.threshold=a.threshold||this.threshold||x.threshold;this.depth=a.depth||this.depth||x.depth;this.h=(b=a.encode)&& +y[b]||("function"===typeof b?b:this.h||!1);(b=a.matcher)&&this.addMatcher(b)}this.b=[{},{},{},{},{},{},{},{},{},{},{}];this.a={};this.f="";this.g=!0;return this};d.prototype.encode=function(a){a&&w.length&&(a=q(a,w));a&&this.c.length&&(a=q(a,this.c));a&&this.h&&(a=this.h.call(y,a));if(a&&this.i){a=a.split(" ");for(var b=0;bh;l--)u=n.substring(h,l),v(p,g,u,a,b,e);break;default:if(h=v(p,g,n,a,b,e),f&&1=e)for(h=p[10],r=g._ctx[n]||(g._ctx[n]={}),n=h[n]||(h[n]=[{},{},{},{},{},{},{},{},{},{}]),h=d-f,l=d+f,0>h&&(h=0),l>m-1&&(l=m-1);h<=l;h++)h!==d&&v(n,r,k[h],a,b,e)}}}this.a[a]="1";this.g=!1}return this};d.prototype.update=function(a,b){"string"===typeof b&&(a||0===a)&&this.a[a]&&(this.remove(a),b&&this.add(a,b));return this};d.prototype.remove= +function(a){if(this.a[a]){for(var b=0;10>b;b++)for(var c=Object.keys(this.b[b]),k=0;k=g;z--)if(w=(r?h[u]:this.b)[z][t])v[y++]= +w,x=!0;if(x)l[l.length]=1g&&(a=a[k],a=a[c]||(a[c]=[]),a[a.length]=e)}return k||b[c]}function x(a){var b=[];if(!a)return b;for(var c=0,e=0,h=0,g="",k=a.length,B=0;Ba?1:0a?-1:0b&&(c=c.slice(0,b)));return c}function E(a){a.B||(a.B=H(function(){a.B=null;var b=a.async;b&&(a.async=!1);if(a.c.length){for(var c=I(),e;(e=a.c.shift())||0===e;){var d=a.h[e];switch(d[0]){case D.add:a.add(d[1],d[2]);break;case D.update:a.update(d[1],d[2]);break;case D.remove:a.remove(d[1])}a.h[e]=null;delete a.h[e];if(100=d&&(b.o=b.b),b.w&&b.o===b.b&&(b.i.length?b.f="":b.f||(b.f=c),b.cache&&b.l.set(c,b.i),b.w(b.i),b.i=[]))})}this.mode=a.mode||this.mode||u.mode;this.cache=a.cache||this.cache||u.cache;this.async=a.async||this.async||u.async;this.b=a.worker||this.b||u.b;this.threshold=a.threshold||this.threshold||u.threshold;this.depth=a.depth||this.depth||u.depth;this.v=a.encode&&y[a.encode]||("function"===typeof a.encode?a.encode:this.v||!1);this.C=a.debug||this.C;a.matcher&&this.addMatcher(a.matcher); -a.filter&&(this.A=M(!0===a.filter?S:a.filter,this.v));a.stemmer&&(this.D=N(!0===a.stemmer?G:a.stemmer,this.v))}this.g=[{},{},{},{},{},{},{},{},{},{},{}];this.a={};this.h={};this.c=[];this.B=null;this.f="";this.u=!0;this.l=this.cache?new T(3E4,50,!0):!1;return this};f.prototype.encode=function(a){a&&z.length&&(a=v(a,z));a&&this.m.length&&(a=v(a,this.m));a&&this.v&&(a=this.v.call(y,a));if(a&&this.A){a=a.split(" ");for(var b=0;b=this.j.length&&(this.s=0),this.j[this.s].postMessage(this.s,{add:!0,id:a,content:b}),this.a[a]=""+this.s,this;if(this.async)return this.h[a]||(this.c[this.c.length]=a),this.h[a]=[D.add,a,b],E(this),this;b=this.encode(b); -if(!b.length)return this;for(var c=this.mode,e="function"===typeof c?c(b):"ngram"===c?x(b):b.split(J),d={_ctx:{}},g=this.threshold,k=this.depth,f=this.g,n=e.length,q=0;ql;A--)t=m.substring(l,A),w(f,d,t,a,b,g);break;default:if(l=w(f,d,m,a,b,g),k&&1g)for(l=f[10], -r=d._ctx[m]||(d._ctx[m]={}),m=l[m]||(l[m]=[{},{},{},{},{},{},{},{},{},{}]),l=q-k,A=q+k,0>l&&(l=0),A>n-1&&(A=n-1);l<=A;l++)l!==q&&w(m,r,e[l],a,b,g)}}}this.a[a]="1";this.u=!1}return this};f.prototype.update=function(a,b){if("string"===typeof b&&(a||0===a)&&this.a[a]){if(this.b){var c=parseInt(this.a[a],10);this.j[c].postMessage(c,{update:!0,id:a,content:b});return this}if(this.async)return this.h[a]||(this.c[this.c.length]=a),this.h[a]=[D.update,a,b],E(this),this;this.remove(a);b&&this.add(a,b)}return this}; -f.prototype.remove=function(a){if(this.a[a]){if(this.b){var b=parseInt(this.a[a],10);this.j[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.h[a]||(this.c[this.c.length]=a),this.h[a]=[D.remove,a],E(this),this;for(b=0;10>b;b++)for(var c=Object.keys(this.g[b]),d=0;d=h;z--)if(v=(r?l[t]:this.g)[z][p])u[y++]=v,w=!0;if(w)q[q.length]=1k;k++)for(b=Object.keys(this.g[k]),a=0;a=k&&(a=a[h],a=a[c]||(a[c]=[]),a[a.length]=e)}return h||b[c]}function x(a){var b=[];if(!a)return b;for(var c=0,e=0,f=0,k="",h=a.length,B=0;Ba?1:0a?-1:0b&&(c=c.slice(0,b)));return c}function E(a){a.B||(a.B=I(function(){a.B=null;var b=a.async;b&&(a.async=!1);if(a.c.length){for(var c=J(),e;(e=a.c.shift())||0===e;){var f=a.h[e];switch(f[0]){case D.add:a.add(f[1],f[2]);break;case D.update:a.update(f[1],f[2]);break;case D.remove:a.remove(f[1])}a.h[e]=null;delete a.h[e];if(100=f&&(c.o=c.b),c.w&&c.o===c.b&&(c.i.length?c.f="":c.f||(c.f=b),c.cache&&c.l.set(b,c.i),c.w(c.i),c.i=[]))})}if(b=a.profile)if(b=G[b])for(var f in b)b.hasOwnProperty(f)&&"undefined"===typeof a[f]&&(a[f]=b[f]);this.mode=a.mode||this.mode||v.mode;this.cache=a.cache||this.cache||v.cache;this.async=a.async||this.async||v.async;this.b=a.worker||this.b||v.b;this.threshold=a.threshold||this.threshold||v.threshold;this.depth=a.depth||this.depth||v.depth;this.v=(b=a.encode)&&y[b]||("function"=== +typeof b?b:this.v||!1);this.C=a.debug||this.C;(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.A=N(!0===b?T:b,this.v);if(b=a.stemmer)this.D=O(!0===b?H:b,this.v)}this.g=[{},{},{},{},{},{},{},{},{},{},{}];this.a={};this.h={};this.c=[];this.B=null;this.f="";this.u=!0;this.l=this.cache?new U(3E4,50,!0):!1;return this};g.prototype.encode=function(a){a&&z.length&&(a=w(a,z));a&&this.m.length&&(a=w(a,this.m));a&&this.v&&(a=this.v.call(y,a));if(a&&this.A){a=a.split(" ");for(var b=0;b=this.j.length&&(this.s=0),this.j[this.s].postMessage(this.s,{add:!0,id:a,content:b}),this.a[a]=""+this.s,this;if(this.async)return this.h[a]||(this.c[this.c.length]= +a),this.h[a]=[D.add,a,b],E(this),this;b=this.encode(b);if(!b.length)return this;for(var c=this.mode,e="function"===typeof c?c(b):"ngram"===c?x(b):b.split(K),f={_ctx:{}},d=this.threshold,h=this.depth,g=this.g,n=e.length,q=0;ql;A--)u=m.substring(l,A),t(g,f,u,a,b,d);break; +default:if(l=t(g,f,m,a,b,d),h&&1=d)for(l=g[10],r=f._ctx[m]||(f._ctx[m]={}),m=l[m]||(l[m]=[{},{},{},{},{},{},{},{},{},{}]),l=q-h,A=q+h,0>l&&(l=0),A>n-1&&(A=n-1);l<=A;l++)l!==q&&t(m,r,e[l],a,b,d)}}}this.a[a]="1";this.u=!1}return this};g.prototype.update=function(a,b){if("string"===typeof b&&(a||0===a)&&this.a[a]){if(this.b){var c=parseInt(this.a[a],10);this.j[c].postMessage(c,{update:!0,id:a,content:b});return this}if(this.async)return this.h[a]||(this.c[this.c.length]=a),this.h[a]=[D.update, +a,b],E(this),this;this.remove(a);b&&this.add(a,b)}return this};g.prototype.remove=function(a){if(this.a[a]){if(this.b){var b=parseInt(this.a[a],10);this.j[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.h[a]||(this.c[this.c.length]=a),this.h[a]=[D.remove,a],E(this),this;for(b=0;10>b;b++)for(var c=Object.keys(this.g[b]),e=0;e=d;z--)if(v=(r?l[u]:this.g)[z][p])t[y++]= +v,w=!0;if(w)q[q.length]=1h;h++)for(b=Object.keys(this.g[h]),a=0;a + + + + Matching Test + + + + +

    Relevance Scoring Comparison

    +

    Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Querydefaultmemoryspeedmatchingscoringbalancedfastest
    "without breach of modesty"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "went softly stream"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "princes of the ambition"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "five-thousand leagues"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "i already observed"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "let a of his"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "take that to the rocks"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "bignes of splaknuk"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "matematikal musikal instruments"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "matical sical strument"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    "lalkon the camberlayhn"wait ...wait ...wait ...wait ...wait ...wait ...wait ...
    +
    +
    +Red: No results.
    +Yellow: Most relevant result is not on top.
    +Green: Most relevant result was successfully found on top.

    +Note: Open console and type e.g. data[493] + + + diff --git a/test/matching.html b/test/matching.html index ba79fd1..5de70d0 100644 --- a/test/matching.html +++ b/test/matching.html @@ -152,6 +152,18 @@ var text_data = "LIBRARY OF THE FUTURE (R) First Edition Ver. 4.02 Gulliver's Tr wait ... + "matical sical strument" + wait ... + wait ... + wait ... + wait ... + wait ... + wait ... + wait ... + wait ... + wait ... + + "lalkon the camberlayhn" wait ... wait ... @@ -166,11 +178,13 @@ var text_data = "LIBRARY OF THE FUTURE (R) First Edition Ver. 4.02 Gulliver's Tr
    +Red: No results.
    +Yellow: Most relevant result is not on the first place.
    +Green: Most relevant result was was successfully found on the first place.

    Note: Open console and type e.g. data[493]