mirror of
https://github.com/nextapps-de/flexsearch.git
synced 2025-08-28 08:10:54 +02:00
-- INITIAL COMMIT --
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
.db
|
||||
!*.keep
|
3
.travis.yml
Normal file
3
.travis.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js: stable
|
||||
after_success: npm run coverage
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
793
README.md
Normal file
793
README.md
Normal file
@@ -0,0 +1,793 @@
|
||||
<p align="center">
|
||||
<br>
|
||||
<img src="http://nextapps.de/img/flexsearch.svg" alt="Search Library" width="50%">
|
||||
<br><br>
|
||||
<a target="_blank" href="https://www.npmjs.com/package/flexsearch"><img src="https://img.shields.io/npm/v/flexsearch.svg"></a>
|
||||
<img src="https://img.shields.io/badge/status-BETA-orange.svg">
|
||||
<a target="_blank" href="https://travis-ci.org/nextapps-de/flexsearch"><img src="https://travis-ci.org/nextapps-de/flexsearch.svg?branch=master"></a>
|
||||
<a target="_blank" href="https://coveralls.io/github/nextapps-de/flexsearch?branch=master"><img src="https://coveralls.io/repos/github/nextapps-de/flexsearch/badge.svg?branch=master"></a>
|
||||
<a target="_blank" href="https://github.com/nextapps-de/flexsearch/issues"><img src="https://img.shields.io/github/issues/nextapps-de/xone.svg"></a>
|
||||
<img src="https://badges.greenkeeper.io/nextapps-de/flexsearch.svg">
|
||||
<a target="_blank" href="https://github.com/nextapps-de/flexsearch/blob/master/LICENSE.md"><img src="https://img.shields.io/npm/l/xone.svg"></a>
|
||||
</p>
|
||||
|
||||
<h1></h1>
|
||||
<h3>Worlds fastest and most memory efficient full text search library with zero dependencies.</h3>
|
||||
|
||||
When it comes to raw search speed <a href="https://jsperf.com/compare-search-libraries" target="_blank">FlexSearch outperforms every single searching library out there</a> 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 existing items from the index has a significant cost. When your index needs to be updated continuously then <a href="bulksearch/" target="_blank">BulkSearch</a> 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.
|
||||
|
||||
Benchmark:
|
||||
- Library Comparison: <a href="https://jsperf.com/compare-search-libraries" target="_blank">https://jsperf.com/compare-search-libraries</a>
|
||||
- BulkSearch vs. FlexSearch: <a href="https://jsperf.com/flexsearch" target="_blank">https://jsperf.com/flexsearch</a>
|
||||
|
||||
Supported Platforms:
|
||||
- Browser
|
||||
- Node.js
|
||||
|
||||
Supported Module Definitions:
|
||||
- AMD (RequireJS)
|
||||
- CommonJS (Node.js)
|
||||
- Closure (Xone)
|
||||
- Global (Browser)
|
||||
|
||||
All Features:
|
||||
<ul>
|
||||
<li><a href="#webworker">Web-Worker Support</a> (not available in Node.js)</li>
|
||||
<li>Partial Matching</li>
|
||||
<li>Multiple Words</li>
|
||||
<li><a href="#phonetic">Phonetic Search</a></li>
|
||||
<li>Relevance-based Scoring</li>
|
||||
<li>Contextual Indexes</li>
|
||||
<li>Limit Results</li>
|
||||
<li>Caching</li>
|
||||
<li>Asynchronous Mode</li>
|
||||
<li>Custom Matchers</li>
|
||||
<li>Custom Encoders</li>
|
||||
</ul>
|
||||
|
||||
<a name="contextual"></a>
|
||||
#### Contextual Search
|
||||
|
||||
FlexSearch introduce a new scoring mechanism called __Contextual Search__ which was invented by Thomas Wilkerling, the author of this library. A Contextual Search __incredibly boost up queries to a new level__.
|
||||
The basic idea of this concept is to limit relevance by context instead of calculating relevance through the whole (unlimited) distance.
|
||||
Imagine you add a text block of some sentences to an index ID. Assuming the query includes a combination of first and last word from this text block, are they really relevant to each other?
|
||||
In this way contextual search also improves the results of relevance-based queries on large amount of text data.
|
||||
|
||||
<br>
|
||||
<p align="center">
|
||||
<img src="https://rawgithub.com/nextapps-de/flexsearch/master/contextual_index.svg">
|
||||
</p>
|
||||
<br>
|
||||
|
||||
__Note:__ This feature is actually not enabled by default.
|
||||
|
||||
<a name="webworker"></a>
|
||||
#### Web-Worker Support
|
||||
|
||||
Workers get its own dedicated memory. Especially for larger indexes, web worker improves speed and available memory a lot. FlexSearch index was tested with a 250 Mb text file including 10 Million words. The indexing was done silently in background by multiple parallel running workers in about 7 minutes. The final index reserves ~ 8.2 Mb memory/space. The search result took ~ 0.25 ms.
|
||||
|
||||
__Note:__ It is slightly faster to use no web worker when the index or query isn't too big (index < 500,000 words, query < 25 words).
|
||||
|
||||
#### Compare BulkSearch vs. FlexSearch
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Description</th>
|
||||
<td align="left">BulkSearch</th>
|
||||
<td align="left">FlexSearch</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Access</td>
|
||||
<td>Read-Write optimized index</td>
|
||||
<td>Read-Memory optimized index</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>Memory</td>
|
||||
<td>Large: ~ 5 Mb per 100,000 words</td>
|
||||
<td>Tiny: ~ 100 Kb per 100,000 words</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>Usecase</td>
|
||||
<td><ul><li>Limited content</li><li>Use when existing items of the index needs to be updated continously (update, remove)</li><li>Supports pagination</li></ul></td>
|
||||
<td><ul><li>Fastest possible search</li><li>Existing items of the index does not need to be updated continously (update, remove)</li><li>Max out memory capabilities</li></ul></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>Pagination</td>
|
||||
<td>Yes</td>
|
||||
<td>No</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>Ranked Searching</td>
|
||||
<td>No</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>Contextual Index</td>
|
||||
<td>No</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>WebWorker</td>
|
||||
<td>No</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Installation
|
||||
|
||||
##### HTML / Javascript
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
<script src="js/flexsearch.min.js"></script>
|
||||
</head>
|
||||
...
|
||||
```
|
||||
__Note:__ Use _flexsearch.min.js_ for production and _flexsearch.js_ for development.
|
||||
|
||||
Use latest from CDN:
|
||||
```html
|
||||
<script src="https://cdn.rawgit.com/nextapps-de/flexsearch/master/flexsearch.min.js"></script>
|
||||
```
|
||||
|
||||
##### Node.js
|
||||
|
||||
```npm
|
||||
npm install flexsearch
|
||||
```
|
||||
|
||||
In your code include as follows:
|
||||
|
||||
```javascript
|
||||
var FlexSearch = require("flexsearch");
|
||||
```
|
||||
|
||||
Or pass in options when requiring:
|
||||
|
||||
```javascript
|
||||
var index = require("flexsearch").create({/* options */});
|
||||
```
|
||||
|
||||
__AMD__
|
||||
|
||||
```javascript
|
||||
var FlexSearch = require("./flexsearch.js");
|
||||
```
|
||||
|
||||
## API Overview
|
||||
|
||||
Global methods:
|
||||
- <a href="#flexsearch.create">FlexSearch.__create__(\<options\>)</a>
|
||||
- <a href="#flexsearch.addmatcher">FlexSearch.__addMatcher__({_KEY: VALUE_})</a>
|
||||
- <a href="#flexsearch.register">FlexSearch.__register__(name, encoder)</a>
|
||||
- <a href="#flexsearch.encode">FlexSearch.__encode__(name, string)</a>
|
||||
|
||||
Index methods:
|
||||
- <a href="#index.add">Index.__add__(id, string)</a>
|
||||
- <a href="#index.search">Index.__search__(string, \<limit\>, \<callback\>)</a>
|
||||
- <a href="#index.update">Index.__update__(id, string)</a>
|
||||
- <a href="#index.remove">Index.__remove__(id)</a>
|
||||
- <a href="#index.reset">Index.__reset__()</a>
|
||||
- <a href="#index.destroy">Index.__destroy__()</a>
|
||||
- <a href="#index.init">Index.__init__(\<options\>)</a>
|
||||
- <a href="#index.info">Index.__info__()</a>
|
||||
- <a href="#index.addmatcher">Index.__addMatcher__({_KEY: VALUE_})</a>
|
||||
- <a href="#index.encode">Index.__encode__(string)</a>
|
||||
|
||||
## Usage
|
||||
<a name="flexsearch.create"></a>
|
||||
#### Create a new index
|
||||
|
||||
> FlexSearch.__create(\<options\>)__
|
||||
|
||||
```js
|
||||
var index = new FlexSearch();
|
||||
```
|
||||
|
||||
alternatively you can also use:
|
||||
|
||||
```js
|
||||
var index = FlexSearch.create();
|
||||
```
|
||||
|
||||
##### Create a new index with custom options
|
||||
|
||||
```js
|
||||
var index = new FlexSearch({
|
||||
|
||||
// default values:
|
||||
|
||||
encode: "icase",
|
||||
mode: "forward",
|
||||
multi: false,
|
||||
async: false,
|
||||
cache: false
|
||||
});
|
||||
```
|
||||
|
||||
__Read more:__ <a href="#phonetic">Phonetic Search</a>, <a href="#compare">Phonetic Comparison</a>, <a href="#memory">Improve Memory Usage</a>
|
||||
<a name="index.add"></a>
|
||||
#### Add items to an index
|
||||
|
||||
> Index.__add___(id, string)
|
||||
|
||||
```js
|
||||
index.add(10025, "John Doe");
|
||||
```
|
||||
<a name="index.search"></a>
|
||||
#### Search items
|
||||
|
||||
> Index.__search(string|options, \<limit\>, \<callback\>)__
|
||||
|
||||
```js
|
||||
index.search("John");
|
||||
```
|
||||
|
||||
Limit the result:
|
||||
|
||||
```js
|
||||
index.search("John", 10);
|
||||
```
|
||||
|
||||
Perform queries asynchronously:
|
||||
|
||||
```js
|
||||
index.search("John", function(result){
|
||||
|
||||
// array of results
|
||||
});
|
||||
```
|
||||
<a name="index.update"></a>
|
||||
#### Update item to the index
|
||||
|
||||
> Index.__update__(id, string)
|
||||
|
||||
```js
|
||||
index.update(10025, "Road Runner");
|
||||
```
|
||||
<a name="index.remove"></a>
|
||||
#### Remove item to the index
|
||||
|
||||
> Index.__remove__(id)
|
||||
|
||||
```js
|
||||
index.remove(10025);
|
||||
```
|
||||
<a name="index.reset"></a>
|
||||
#### Reset index
|
||||
|
||||
```js
|
||||
index.reset();
|
||||
```
|
||||
<a name="index.destroy"></a>
|
||||
#### Destroy the index
|
||||
|
||||
```js
|
||||
index.destroy();
|
||||
```
|
||||
<a name="index.init"></a>
|
||||
#### Re-Initialize index
|
||||
|
||||
> Index.__init(\<options\>)__
|
||||
|
||||
__Note:__ Re-initialization will also destroy the old index!
|
||||
|
||||
Initialize (with same options):
|
||||
```js
|
||||
index.init();
|
||||
```
|
||||
|
||||
Initialize with new options:
|
||||
```js
|
||||
index.init({
|
||||
|
||||
/* options */
|
||||
});
|
||||
```
|
||||
<a name="flexsearch.addmatcher"></a>
|
||||
#### Add custom matcher
|
||||
|
||||
> FlexSearch.__addMatcher({_REGEX: REPLACE_})__
|
||||
|
||||
Add global matchers for all instances:
|
||||
```js
|
||||
FlexSearch.addMatcher({
|
||||
|
||||
'ä': 'a', // replaces all 'ä' to 'a'
|
||||
'ó': 'o',
|
||||
'[ûúù]': 'u' // replaces multiple
|
||||
});
|
||||
```
|
||||
<a name="index.addmatcher"></a>
|
||||
Add private matchers for a specific instance:
|
||||
```js
|
||||
index.addMatcher({
|
||||
|
||||
'ä': 'a', // replaces all 'ä' to 'a'
|
||||
'ó': 'o',
|
||||
'[ûúù]': 'u' // replaces multiple
|
||||
});
|
||||
```
|
||||
<a name="flexsearch.encoder"></a>
|
||||
#### Add custom encoder
|
||||
|
||||
Define a private custom encoder during creation/initialization:
|
||||
```js
|
||||
var index = new FlexSearch({
|
||||
|
||||
encode: function(str){
|
||||
|
||||
// do something with str ...
|
||||
|
||||
return str;
|
||||
}
|
||||
});
|
||||
```
|
||||
<a name="flexsearch.register"></a>
|
||||
##### Register a global encoder to be used by all instances
|
||||
|
||||
> FlexSearch.__register(name, encoder)__
|
||||
|
||||
```js
|
||||
FlexSearch.register('whitespace', function(str){
|
||||
|
||||
return str.replace(/ /g, '');
|
||||
});
|
||||
```
|
||||
|
||||
Use global encoders:
|
||||
```js
|
||||
var index = new FlexSearch({ encode: 'whitespace' });
|
||||
```
|
||||
<a name="index.encode"></a>
|
||||
##### Call encoders directly
|
||||
|
||||
Private encoder:
|
||||
```js
|
||||
var encoded = index.encode("sample text");
|
||||
```
|
||||
<a name="flexsearch.encode"></a>
|
||||
Global encoder:
|
||||
```js
|
||||
var encoded = FlexSearch.encode("whitespace", "sample text");
|
||||
```
|
||||
|
||||
##### Mixup/Extend multiple encoders
|
||||
|
||||
```js
|
||||
FlexSearch.register('mixed', function(str){
|
||||
|
||||
str = this.encode("icase", str); // built-in
|
||||
str = this.encode("whitespace", str); // custom
|
||||
|
||||
return str;
|
||||
});
|
||||
```
|
||||
```js
|
||||
FlexSearch.register('extended', function(str){
|
||||
|
||||
str = this.encode("custom", str);
|
||||
|
||||
// do something additional with str ...
|
||||
|
||||
return str;
|
||||
});
|
||||
```
|
||||
|
||||
<a name="index.info"></a>
|
||||
#### Get info
|
||||
|
||||
```js
|
||||
index.info();
|
||||
```
|
||||
|
||||
Returns information about the index, e.g.:
|
||||
|
||||
```json
|
||||
{
|
||||
"bytes": 3600356288,
|
||||
"id": 0,
|
||||
"matchers": 0,
|
||||
"size": 10000,
|
||||
"status": false
|
||||
}
|
||||
```
|
||||
<a name="chaining"></a>
|
||||
#### Chaining
|
||||
|
||||
Simply chain methods like:
|
||||
|
||||
```js
|
||||
var index = FlexSearch.create()
|
||||
.addMatcher({'â': 'a'})
|
||||
.add(0, 'foo')
|
||||
.add(1, 'bar');
|
||||
```
|
||||
|
||||
```js
|
||||
index.remove(0).update(1, 'foo').add(2, 'foobar');
|
||||
```
|
||||
|
||||
<a name="options"></a>
|
||||
## Options
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Option</td>
|
||||
<td align="left">Values</td>
|
||||
<td align="left">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="top">mode<br><br><br><br><br></td>
|
||||
<td vertical="top" vertical-align="top">
|
||||
"strict"<br>
|
||||
"foward"<br>
|
||||
"reverse"<br>
|
||||
"ngram"<br>
|
||||
"full"
|
||||
</td>
|
||||
<td vertical-align="top">
|
||||
The <a href="#tokenizer">indexing mode (tokenizer)</a>.<br><br><br><br><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">encode<br><br><br><br><br><br></td>
|
||||
<td>
|
||||
false<br>
|
||||
"icase"<br>
|
||||
"simple"<br>
|
||||
"advanced"<br>
|
||||
"extra"<br>
|
||||
function()
|
||||
</td>
|
||||
<td>The encoding type.<br><br>Choose one of the <a href="#phonetic">built-ins</a> or pass a <a href="#flexsearch.encoder">custom encoding function</a>.<br><br><br><br></td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">boolean<br><br></td>
|
||||
<td>
|
||||
"and"<br>
|
||||
"or"
|
||||
</td>
|
||||
<td>The applied boolean model when comparing multiple words. <b>Note:</b> When using "or" the first word is also compared with "and". Example: a query with 3 words, results has either: matched word 1 & 2 and matched word 1 & 3.</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">multi<br><br></td>
|
||||
<td>
|
||||
true<br>
|
||||
false
|
||||
</td>
|
||||
<td>Enable multi word processing.<br><br></td>
|
||||
</tr>
|
||||
-->
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">cache<br><br></td>
|
||||
<td>
|
||||
true<br>
|
||||
false
|
||||
</td>
|
||||
<td>Enable/Disable caching.<br><br></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">async<br><br></td>
|
||||
<td>
|
||||
true<br>
|
||||
false
|
||||
</td>
|
||||
<td>Enable/Disable asynchronous processing.<br><br></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">worker<br><br></td>
|
||||
<td>
|
||||
false<br>
|
||||
{number}
|
||||
</td>
|
||||
<td>Enable/Disable and set count of running worker threads.<br><br></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="top">depth<br><br></td>
|
||||
<td>
|
||||
false<br>
|
||||
{number}
|
||||
</td>
|
||||
<td>Enable/Disable contextual indexing and also sets relevance depth (experimental).<br><br></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="tokenizer"></a>
|
||||
## Tokenizer
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Option</td>
|
||||
<td align="left">Description</td>
|
||||
<td align="left">Example</td>
|
||||
<td align="left">Memory Factor (n = length of word)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>"strict"</b></td>
|
||||
<td>index whole words</td>
|
||||
<td><b>foobar</b></td>
|
||||
<td>* 1</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"foward"</b></td>
|
||||
<td>incrementally index words in forward direction</td>
|
||||
<td><b>fo</b>obar<br><b>foob</b>ar<br></td>
|
||||
<td>* n</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"reverse"</b></td>
|
||||
<td>incrementally index words in both directions</td>
|
||||
<td>foob<b>ar</b><br>fo<b>obar</b></td>
|
||||
<td>* 2n</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"ngram"</b> (default)</td>
|
||||
<td>index words partially through phonetic n-grams</td>
|
||||
<td><b>foo</b>bar<br>foo<b>bar</b></td>
|
||||
<td>* n/4</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"full"</b></td>
|
||||
<td>index every possible combination</td>
|
||||
<td>fo<b>oba</b>r<br>f<b>oob</b>ar</td>
|
||||
<td>* n*(n-1)</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<a name="phonetic"></a>
|
||||
## Phonetic Encoding
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Option</td>
|
||||
<td align="left">Description</td>
|
||||
<td align="left">False-Positives</td>
|
||||
<td align="left">Compression</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>false</b></td>
|
||||
<td>Turn off encoding</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"icase"</b> (default)</td>
|
||||
<td>Case in-sensitive encoding</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"simple"</b></td>
|
||||
<td>Phonetic normalizations</td>
|
||||
<td>no</td>
|
||||
<td>~ 7%</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"advanced"</b></td>
|
||||
<td>Phonetic normalizations + Literal transformations</td>
|
||||
<td>no</td>
|
||||
<td>~ 35%</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>"extra"</b></td>
|
||||
<td>Phonetic normalizations + Soundex transformations</td>
|
||||
<td>yes</td>
|
||||
<td>~ 60%</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td><b>function()</b></td>
|
||||
<td>Pass custom encoding: function(string):string</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="compare" id="compare"></a>
|
||||
#### Comparison
|
||||
|
||||
Reference String: __"Björn-Phillipp Mayer"__
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Query</td>
|
||||
<td align="left">iCase</td>
|
||||
<td align="left">Simple</td>
|
||||
<td align="left">Advanced</td>
|
||||
<td align="left">Extra</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>björn</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>björ</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>bjorn</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>bjoern</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>philipp</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>filip</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>björnphillip</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>meier</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>björn meier</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>meier fhilip</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>byorn mair</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td>no</td>
|
||||
<td><b>yes</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i>(false positives)</i></td>
|
||||
<td><b>no</b></td>
|
||||
<td><b>no</b></td>
|
||||
<td><b>no</b></td>
|
||||
<td>yes</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a name="memory" id="memory"></a>
|
||||
## Memory Usage
|
||||
|
||||
__Note:__ The required memory depends on several options.
|
||||
|
||||
<table>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td align="left">Encoding</td>
|
||||
<td align="left">Memory usage of every ~ 100,000 indexed words</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>false</td>
|
||||
<td>260 kb</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"icase" (default)</td>
|
||||
<td>210 kb</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"simple"</td>
|
||||
<td>190 kb</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"advanced"</td>
|
||||
<td>150 kb</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"extra"</td>
|
||||
<td>90 kb</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">Mode</td>
|
||||
<td align="left">Multiplied with: (n = <u>average</u> length of all words)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>"strict"</td>
|
||||
<td>* 1</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"forward"</td>
|
||||
<td>* n</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"reverse"</td>
|
||||
<td>* 2n</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"ngram" (default)</td>
|
||||
<td>* n/4</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
<tr>
|
||||
<td>"full"</td>
|
||||
<td>* n*(n-1)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
Author FlexSearch: Thomas Wilkerling<br>
|
||||
License: <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache 2.0 License</a><br>
|
2
contextual_index.svg
Normal file
2
contextual_index.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
2126
flexsearch.js
Normal file
2126
flexsearch.js
Normal file
File diff suppressed because it is too large
Load Diff
25
flexsearch.min.js
vendored
Normal file
25
flexsearch.min.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
https://github.com/nextapps-de/flexsearch
|
||||
@version: 0.2.0
|
||||
@license: Apache 2.0 Licence
|
||||
*/
|
||||
'use strict';(function(l,C,e){var d;(d=e.define)&&d.amd?d([],function(){return C}):(d=e.modules)?d[l.toLowerCase()]=C:"undefined"!==typeof module?module.exports=C:e[l]=C})("FlexSearch",function G(l){function e(a){a||(a=u);this.id=a.id||H++;this.init(a);Object.defineProperty(this,"index",{get:function(){return this.a}});Object.defineProperty(this,"length",{get:function(){return Object.keys(this.a).length}})}function d(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 r(a,b,c,f,h,t){if("undefined"===typeof b[c]){var g=h.indexOf(c);g=3/h.length*(h.length-g)+6/(g-h.lastIndexOf(" ",g))+.5|0;b[c]=g;g>t&&(a=a[g],a=a[c]||(a[c]=[]),a[a.length]=f)}return g||b[c]}function w(a){for(var b="",c="",f="",h=0;h<a.length;h++){var t=a[h];t!==c&&(0<h&&"h"===t?(f="a"===f||"e"===f||"i"===f||"o"===f||"u"===f||"y"===f,"a"!==c&&"e"!==c&&"i"!==c&&"o"!==c&&"u"!==c&&"y"!==c||!f||(b+=t)):b+=t);f=h===a.length-
|
||||
1?"":a[h+1];c=t}return b}function x(a,b){a=a.length-b.length;return 0>a?1:0<a?-1:0}function I(a,b){a=a.length-b.length;return 0>a?-1:0<a?1:0}function J(a,b){var c=[],f=a.length;if(1<f){a.sort(I);for(var h={},t=a[0],g=0,y=t.length;g<y;++g)h[t[g]]=1;for(var d=0,e=1;e<f;++e){var n=a[e],m=!1;g=0;for(y=n.length;g<y;++g)if(h[t=n[g]]===e){if(e===f-1&&(c[d++]=t,b&&d===b))return c;m=!0;h[t]=e+1;break}if(!m)return[]}}else f&&(c=a[0],b&&c&&c.length>b&&(c=c.slice(0,b)));return c}function B(a){a.w||(a.w=D(function(){a.w=
|
||||
null;var b=a.async;b&&(a.async=!1);if(a.c.length){for(var c=E(),f;(f=a.c.shift())||0===f;){var h=a.h[f];switch(h[0]){case z.add:a.add(h[1],h[2]);break;case z.update:a.update(h[1],h[2]);break;case z.remove:a.remove(h[1])}a.h[f]=null;delete a.h[f];if(100<E()-c)break}a.c.length&&B(a)}b&&(a.async=b)},1,"search-async-"+a.id))}function E(){return"undefined"!==typeof performance?performance.now():(new Date).getTime()}function K(a,b,c,f){a=l("flexsearch","id"+a,function(){var a,b;self.a=function(c){if(c=
|
||||
c.data)c.search?self.postMessage({result:b.search(c.content,c.threshold?{limit:c.limit,threshold:c.threshold}:c.limit),id:a,content:c.content,limit:c.limit}):c.add?b.add(c.id,c.content):c.update?b.update(c.id,c.content):c.remove?b.remove(c.id):c.reset?b.reset():c.info?(c=b.info(),c.worker=a,b.A&&console.log(c)):c.register&&(a=c.id,c.options.cache=!1,c.options.async=!0,c.options.worker=!1,b=(new Function(c.register.substring(c.register.indexOf("{")+1,c.register.lastIndexOf("}"))))(),b=new b(c.options))}},
|
||||
function(a){(a=a.data)&&a.result&&f(a.id,a.content,a.result,a.limit)},b);var h=G.toString();c.id=b;a.postMessage(b,{register:h,options:c,id:b});return a}var u={type:"integer",mode:"forward",cache:!1,async:!1,b:!1,threshold:0,depth:0,encode:!1},v=[],H=0,z={add:0,update:1,remove:2},F=d("[ -/]");e.new=function(a){return new this(a)};e.create=function(a){return e.new(a)};e.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(v[v.length]=d(b),v[v.length]=a[b]);return this};e.register=function(a,
|
||||
b){A[a]=b;return this};e.encode=function(a,b){return A[a](b)};e.prototype.init=function(a){this.m=[];if(a){if(a.worker)if("undefined"===typeof Worker)a.worker=!1,a.async=!0,this.j=null;else{var b=this,c=parseInt(a.worker,10)||4;b.s=-1;b.o=0;b.i=[];b.v=null;b.j=Array(c);for(var f=0;f<c;f++)b.j[f]=K(b.id,f,a||u,function(a,c,f,d){b.o!==b.b&&(b.i=b.i.concat(f),b.o++,d&&b.i.length>=d&&(b.o=b.b),b.v&&b.o===b.b&&(b.i.length?b.f="":b.f||(b.f=c),b.cache&&b.l.set(c,b.i),b.v(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.encoder=a.encode&&A[a.encode]||this.encoder||a.encode;this.A=a.debug||this.A;a.matcher&&this.addMatcher(a.matcher)}this.g=[{},{},{},{},{},{},{},{},{},{},{}];this.a={};this.h={};this.c=[];this.w=null;this.f="";this.u=!0;this.l=this.cache?new L(3E4,50,!0):!1;return this};e.prototype.encode=
|
||||
function(a){a&&v.length&&(a=q(a,v));a&&this.m.length&&(a=q(a,this.m));a&&this.encoder&&(a=this.encoder.call(A,a));return a};e.prototype.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(this.m[this.m.length]=d(b),this.m[this.m.length]=a[b]);return this};e.prototype.add=function(a,b){if("string"===typeof b&&b&&(a||0===a))if(this.a[a])this.update(a,b);else{if(this.b)return++this.s>=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]=[z.add,a,b],B(this),this;b=this.encode(b);if(!b.length)return this;for(var c=b.constructor===Array?b:b.split(F),f={_ctx:{}},h=this.threshold,d=this.g,g=c.length,e=0;e<g;e++){var k=c[e];if(k){var p=k.length;switch(this.mode){case "reverse":case "both":for(var n="",m=p-1;1<=m;m--)n=k[m]+n,r(d,f,n,a,b,h);case "forward":n="";for(m=0;m<p;m++)n+=k[m],r(d,f,n,a,b,h);break;case "full":for(m=0;m<p;m++)for(var l=p;l>m;l--)n=k.substring(m,l),
|
||||
r(d,f,n,a,b,h);break;case "ngram":break;default:p=r(d,f,k,a,b,h),1<g&&this.depth&&p>h&&(n=d[10],p=f._ctx[k]||(f._ctx[k]={}),k=n[k]||(n[k]=[{},{},{},{},{},{},{},{},{},{}]),e&&(1<e&&r(k,p,c[e-2],a,b,h),r(k,p,c[e-1],a,b,h)),e<g-1&&(r(k,p,c[e+1],a,b,h),e<g-2&&r(k,p,c[e+2],a,b,h)))}}}this.a[a]="1";this.u=!1}return this};e.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]=[z.update,a,b],B(this),this;this.remove(a);b&&this.add(a,b)}return this};e.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]=[z.remove,a],B(this),this;for(b=0;10>b;b++)for(var c=Object.keys(this.g[b]),f=0;f<c.length;f++){var d=c[f],e=this.g[b];if((e=e&&e[d])&&e.length)for(var g=0;g<e.length;g++)if(e[g]===
|
||||
a){e.splice(g,1);break}e.length||delete this.g[b][d]}delete this.a[a];this.u=!1}return this};e.prototype.search=function(a,b,c){var f=[];if(a&&"object"===typeof a){c=a.callback||b;b=a.limit;var d=a.threshold;a=a.query}d||(d=0);"function"===typeof b?(c=b,b=1E3):b||(b=1E3);if(this.b){this.v=c;this.o=0;this.i=[];for(f=0;f<this.b;f++)this.j[f].postMessage(f,{search:!0,limit:b,threshold:d,content:a});return null}if(c){var e=this;D(function(){c(e.search(a,b));e=null},1,"search-"+this.id);return null}if(!a||
|
||||
"string"!==typeof a)return f;var g=a;if(!this.u)this.cache&&(this.f="",this.l.reset()),this.u=!0;else if(this.cache){var y=this.l.get(a);if(y)return y}else if(this.f&&0===a.indexOf(this.f))return f;g=this.encode(g);if(!g.length)return f;g=g.constructor===Array?g:g.split(F);y=g.length;var k=!0,p=[],n={};if(1<y)if(this.depth){var m=!0,l=g[0];n[l]="1"}else g.sort(x);var r;if(!m||(r=this.g[10])[l])for(var u=m?1:0;u<y;u++){var q=g[u];if(q&&!n[q]){for(var v,z=!1,w=[],B=0,A=9;A>=d;A--)if(v=m?r[l][A][q]:
|
||||
this.g[A][q])w[B++]=v,z=!0;if(z)p[p.length]=1<B?p.concat.apply([],w):w[0];else{k=!1;break}n[q]="1"}l=q}else k=!1;k&&(f=J(p,b));f.length?this.f="":this.f||(this.f=a);this.cache&&this.l.set(a,f);return f};e.prototype.info=function(){if(this.b)for(var a=0;a<this.b;a++)this.j[a].postMessage(a,{info:!0,id:this.id});else{for(var b,c,f=0,d=0,e=0,g=0;10>g;g++)for(b=Object.keys(this.g[g]),a=0;a<b.length;a++)c=this.g[g][b[a]].length,f+=c+2*b[a].length+4,d+=c,e+=2*b[a].length;b=Object.keys(this.a);c=b.length;
|
||||
for(a=0;a<c;a++)f+=2*b[a].length+2;return{id:this.id,memory:f,items:c,sequences:d,chars:e,status:this.u,cache:this.c.length,matcher:v.length,worker:this.b}}};e.prototype.reset=function(){this.destroy();return this.init()};e.prototype.destroy=function(){this.cache&&this.l.reset();this.g=this.a=this.l=null;return this};var A={icase:function(a){return a.toLowerCase()},simple:function(){var a=[d("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",d("[\u00e8\u00e9\u00ea\u00eb]"),"e",d("[\u00ec\u00ed\u00ee\u00ef]"),
|
||||
"i",d("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",d("[\u00f9\u00fa\u00fb\u00fc\u0171]"),"u",d("[\u00fd\u0177\u00ff]"),"y",d("\u00f1"),"n",d("\u00e7"),"c",d("\u00df"),"s",d("[-/]")," ",d("[^a-z0-9 ]"),""];return function(b){return q(b.toLowerCase(),a)}}(),advanced:function(){var a=[d("ae"),"a",d("ai"),"ei",d("ay"),"ei",d("ey"),"ei",d("oe"),"o",d("ue"),"u",d("ie"),"i",d("sz"),"s",d("zs"),"s",d("sh"),"s",d("ck"),"k",d("cc"),"k",d("dt"),"t",d("ph"),"f",d("pf"),"f",d("ou"),"o",d("uo"),"u"];return function(b,
|
||||
c){if(!b)return b;b=this.simple(b);2<b.length&&(b=q(b,a));c||1<b.length&&(b=w(b));return b}}(),extra:function(){var a=[d("p"),"b",d("z"),"s",d("[cgq]"),"k",d("n"),"m",d("d"),"t",d("[vw]"),"f",d("[aeiouy]"),""];return function(b){if(!b)return b;b=this.advanced(b,!0);if(1<b.length){b=b.split(" ");for(var c=0;c<b.length;c++){var f=b[c];1<f.length&&(b[c]=f[0]+q(f.substring(1),a))}b=b.join("");b=w(b)}return b}}(),ngram:function(a){var b=[];if(!a)return b;a=this.advanced(a);if(!a)return b;for(var c=0,f=
|
||||
0,d=-1,e="",g=a.length,l=0;l<g;l++){var k=a[l];"a"===k||"e"===k||"i"===k||"o"===k||"u"===k||"y"===k?c++:f++;" "!==k&&(e+=k);if(" "===k||2<=c&&2<=f||l===g-1){if(e){c=e.length;if(2<c||" "===k||l===g-1){if(k=e.charCodeAt(0),1<c||48<=k||57>=k)b[++d]=e}else b[d]&&(b[d]+=e);e=""}f=c=0}}return b}},D=function(){var a={};return function(b,c,d){var e=a[d];e&&clearTimeout(e);return a[d]=setTimeout(b,c)}}(),L=function(){function a(){this.cache={}}a.prototype.reset=function(){this.cache={}};a.prototype.set=function(a,
|
||||
c){this.cache[a]=c};a.prototype.get=function(a){return this.cache[a]};return a}();return e}(function(){var l={},C=!("undefined"===typeof Blob||"undefined"===typeof URL||!URL.createObjectURL);return function(e,d,q,r,w){var x=e;e=C?URL.createObjectURL(new Blob(["("+q.toString()+")()"],{type:"text/javascript"})):"../"+x+".js";x+="-"+d;l[x]||(l[x]=[]);l[x][w]=new Worker(e);l[x][w].onmessage=r;return{postMessage:function(d,e){l[x][d].postMessage(e)}}}}()),this);
|
98
flexsearch.svg
Normal file
98
flexsearch.svg
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="3098.000000pt" height="578.000000pt" viewBox="0 0 3098.000000 578.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<g transform="translate(0.000000,578.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path fill="#c21794" d="M3225 5749 c-88 -16 -202 -36 -252 -45 l-93 -16 0 -1898 c0 -1230 4
|
||||
-1934 10 -2001 48 -479 298 -696 836 -727 l113 -7 6 25 c6 29 75 446 75 453 0
|
||||
2 -24 7 -52 10 -82 10 -209 46 -253 72 -87 51 -136 137 -154 268 -8 53 -11
|
||||
691 -11 1988 l0 1909 -32 -1 c-18 -1 -105 -14 -193 -30z"/>
|
||||
<path fill="#1727c2" d="M23800 5744 c-102 -18 -215 -38 -252 -44 l-68 -12 0 -2289 0 -2289
|
||||
285 0 285 0 2 1303 3 1302 76 22 c148 42 315 65 504 70 155 4 194 2 280 -16
|
||||
290 -60 438 -234 499 -587 29 -169 36 -393 36 -1241 l0 -853 280 0 281 0 -3
|
||||
1048 c-4 1046 -4 1047 -27 1172 -40 219 -84 345 -166 483 -143 244 -373 398
|
||||
-697 469 -92 20 -131 22 -373 22 -255 0 -277 -1 -395 -26 -69 -15 -164 -41
|
||||
-212 -57 l-88 -30 0 795 0 794 -32 -1 c-18 -1 -116 -16 -218 -35z"/>
|
||||
<path fill="#1727c2" d="M11100 5355 c-532 -75 -894 -342 -1024 -755 -75 -236 -73 -553 4
|
||||
-774 86 -248 292 -456 610 -615 139 -70 217 -101 595 -241 395 -146 544 -233
|
||||
686 -398 123 -142 174 -348 135 -542 -55 -271 -250 -422 -617 -476 -91 -13
|
||||
-162 -15 -354 -11 -295 6 -412 24 -640 101 -156 53 -340 128 -359 147 -30 29
|
||||
-42 7 -126 -223 -47 -127 -87 -235 -88 -240 -2 -5 43 -30 100 -57 235 -111
|
||||
526 -190 838 -226 165 -20 536 -20 702 0 397 46 693 172 900 382 181 184 263
|
||||
387 275 678 18 429 -113 742 -408 978 -165 132 -384 242 -864 434 -306 123
|
||||
-414 174 -530 251 -92 60 -193 157 -233 223 -59 97 -86 269 -63 394 44 237
|
||||
249 406 560 460 109 20 393 19 530 0 193 -28 426 -97 573 -171 39 -20 74 -32
|
||||
78 -27 5 4 47 107 95 228 48 121 89 225 91 231 7 16 -132 86 -252 127 -127 44
|
||||
-317 91 -454 113 -144 22 -626 29 -760 9z"/>
|
||||
<path fill="#c21794" d="M0 3195 l0 -2085 295 0 295 0 0 955 0 955 855 0 855 0 0 250 0 250
|
||||
-855 0 -855 0 0 625 0 625 965 0 965 0 0 255 0 255 -1260 0 -1260 0 0 -2085z"/>
|
||||
<path fill="#c21794" d="M5235 4304 c-298 -53 -547 -184 -748 -393 -194 -203 -331 -474 -392
|
||||
-775 -61 -304 -57 -680 11 -976 144 -632 591 -1022 1258 -1101 146 -17 570 -6
|
||||
711 19 182 33 438 105 478 135 15 11 13 31 -22 240 -21 125 -40 230 -43 233
|
||||
-3 3 -53 -11 -109 -30 -255 -87 -429 -111 -736 -103 -223 6 -310 20 -447 71
|
||||
-305 115 -497 406 -544 824 l-8 72 1066 0 1067 0 6 78 c8 90 -7 431 -23 547
|
||||
-94 681 -438 1072 -1020 1160 -121 19 -398 18 -505 -1z m465 -492 c285 -93
|
||||
490 -413 490 -763 l0 -69 -765 0 -765 0 0 29 c0 42 53 245 84 321 101 247 308
|
||||
436 544 495 88 22 327 14 412 -13z"/>
|
||||
<path fill="#1727c2" d="M14105 4304 c-298 -53 -547 -184 -748 -393 -194 -203 -331 -474 -392
|
||||
-775 -61 -304 -57 -680 11 -976 143 -626 585 -1017 1244 -1100 177 -22 540
|
||||
-12 740 21 146 24 426 104 463 132 15 11 13 31 -22 240 -21 125 -40 230 -43
|
||||
233 -3 3 -53 -11 -109 -30 -255 -87 -429 -111 -736 -103 -223 6 -310 20 -447
|
||||
71 -305 115 -497 406 -544 824 l-8 72 1066 0 1067 0 6 78 c8 90 -7 431 -23
|
||||
547 -94 681 -438 1072 -1020 1160 -121 19 -398 18 -505 -1z m465 -492 c285
|
||||
-93 490 -413 490 -763 l0 -69 -765 0 -765 0 0 29 c0 42 53 245 84 321 101 247
|
||||
308 436 544 495 88 22 327 14 412 -13z"/>
|
||||
<path fill="#1727c2" d="M16810 4309 c-165 -17 -437 -73 -522 -106 -23 -9 -38 -22 -38 -32 0
|
||||
-9 14 -116 32 -237 l31 -222 54 19 c178 61 444 99 696 99 292 0 419 -40 553
|
||||
-174 128 -128 178 -277 191 -565 l6 -154 -24 6 c-314 78 -706 89 -1013 26
|
||||
-454 -92 -744 -332 -826 -682 -38 -165 -35 -386 9 -552 101 -385 393 -606 885
|
||||
-671 279 -37 838 -7 1344 73 l173 27 -4 1110 c-4 1214 -1 1164 -63 1366 -115
|
||||
375 -397 599 -837 664 -116 18 -497 20 -647 5z m866 -1787 c50 -11 101 -25
|
||||
113 -31 l21 -12 -2 -457 -3 -457 -70 -14 c-50 -9 -170 -14 -415 -14 -330 -2
|
||||
-349 -1 -425 21 -290 82 -405 231 -393 514 4 95 8 113 36 171 76 153 263 263
|
||||
505 297 34 5 170 7 302 5 195 -2 257 -7 331 -23z"/>
|
||||
<path fill="#1727c2" d="M22105 4313 c-316 -40 -612 -181 -821 -390 -224 -223 -371 -525 -435
|
||||
-889 -30 -172 -33 -518 -6 -694 59 -382 189 -662 412 -885 189 -190 435 -318
|
||||
722 -376 135 -27 467 -38 625 -19 237 27 454 74 553 121 l42 20 -40 240 c-35
|
||||
207 -42 239 -56 233 -50 -23 -226 -77 -314 -96 -89 -20 -132 -22 -342 -23
|
||||
-216 0 -249 2 -328 22 -363 93 -580 329 -665 723 -29 135 -45 334 -37 475 27
|
||||
486 192 800 500 951 143 70 220 86 430 91 151 4 200 2 301 -16 114 -19 252
|
||||
-58 336 -95 34 -15 37 -15 42 2 3 9 30 112 61 227 31 116 58 217 61 226 9 31
|
||||
-286 115 -509 144 -108 14 -446 19 -532 8z"/>
|
||||
<path fill="#1727c2" d="M19810 4303 c-204 -19 -494 -79 -722 -150 l-118 -36 0 -1504 0 -1503
|
||||
285 0 285 0 0 1314 0 1313 148 33 c131 30 168 34 341 38 219 5 331 -6 496 -48
|
||||
61 -15 117 -31 125 -34 12 -5 23 38 64 244 27 138 47 253 44 255 -5 6 -122 30
|
||||
-268 57 -94 17 -163 21 -375 23 -143 1 -280 1 -305 -2z"/>
|
||||
<path fill="#c21794" d="M6988 4173 c26 -38 268 -378 536 -756 l488 -689 -28 -38 c-16 -21
|
||||
-101 -132 -190 -247 -285 -369 -527 -705 -671 -933 -95 -149 -223 -372 -223
|
||||
-387 0 -10 57 -13 289 -13 l289 0 52 93 c103 181 273 431 483 712 107 143 259
|
||||
337 292 373 10 11 38 -19 147 -155 283 -352 531 -702 653 -920 l58 -103 281 1
|
||||
c154 1 293 4 308 8 l28 6 -88 150 c-208 355 -379 598 -865 1230 -94 121 -174
|
||||
227 -180 235 -7 13 106 179 512 755 l522 740 -303 3 c-233 2 -305 -1 -314 -10
|
||||
-6 -7 -172 -244 -369 -525 -196 -282 -360 -513 -364 -513 -3 0 -171 236 -372
|
||||
523 l-366 522 -327 3 -326 2 48 -67z"/>
|
||||
<path fill="#b5b5b5" d="M27919 5517 c-149 -63 -229 -201 -216 -372 17 -229 186 -361 424
|
||||
-333 117 14 221 89 272 197 23 50 26 68 26 166 0 98 -3 116 -26 166 -33 70
|
||||
-91 129 -161 166 -46 23 -67 27 -158 30 -92 3 -112 1 -161 -20z"/>
|
||||
<path fill="#b5b5b5" d="M29665 4304 c-316 -49 -572 -193 -715 -403 -95 -141 -134 -280 -133
|
||||
-481 0 -160 17 -250 68 -355 79 -164 225 -302 428 -402 56 -28 212 -97 346
|
||||
-153 484 -201 632 -293 703 -438 31 -62 33 -74 33 -167 0 -93 -3 -106 -30
|
||||
-160 -50 -97 -141 -154 -310 -193 -55 -13 -126 -17 -340 -17 -324 0 -362 6
|
||||
-647 103 -108 36 -199 64 -201 62 -2 -3 -26 -111 -53 -240 -35 -161 -47 -237
|
||||
-40 -243 6 -4 80 -30 164 -57 271 -88 425 -110 776 -110 153 0 272 5 351 15
|
||||
571 75 875 339 910 790 7 99 -6 257 -30 350 -22 88 -87 211 -147 282 -135 159
|
||||
-331 269 -783 438 -224 84 -402 170 -477 229 -179 143 -210 392 -65 536 44 45
|
||||
150 100 242 125 81 23 359 31 497 15 125 -14 305 -59 414 -104 l81 -33 51 245
|
||||
c39 182 49 248 40 253 -18 12 -235 66 -328 83 -262 48 -609 60 -805 30z"/>
|
||||
<path fill="#b5b5b5" d="M27778 2593 l-3 -1648 -23 -79 c-62 -212 -174 -330 -350 -367 -73
|
||||
-15 -297 -6 -372 14 -30 9 -56 14 -58 12 -8 -7 -73 -448 -69 -459 5 -13 88
|
||||
-36 201 -56 33 -5 124 -10 202 -10 220 0 380 34 541 115 231 116 381 313 454
|
||||
600 49 189 49 184 49 1908 l0 1617 -285 0 -285 0 -2 -1647z"/>
|
||||
<path fill="#b5b5b5" d="M26731 1824 c-101 -36 -174 -106 -224 -213 -29 -61 -32 -74 -32 -171
|
||||
0 -97 3 -110 32 -172 81 -173 225 -247 435 -226 223 22 366 219 337 463 -16
|
||||
128 -102 250 -214 302 -53 24 -74 28 -175 30 -86 2 -126 -1 -159 -13z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
46
package.json
Normal file
46
package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "flexsearch",
|
||||
"version": "0.2.0",
|
||||
"description": "Superfast, lightweight and memory efficient full text search library.",
|
||||
"keywords": [],
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextapps-de/flexsearch/issues",
|
||||
"email": "info@nextapps.de"
|
||||
},
|
||||
"main": "flexsearch.js",
|
||||
"preferGlobal": true,
|
||||
"bin": {},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextapps-de/flexsearch.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "java -jar -Xms256m -Xmx4096m node_modules/google-closure-compiler/compiler.jar --compilation_level=ADVANCED_OPTIMIZATIONS --use_types_for_optimization=true --new_type_inf=true --jscomp_warning=newCheckTypes --generate_exports=true --export_local_property_definitions=true --language_in=ECMASCRIPT5_STRICT --language_out=ECMASCRIPT5_STRICT --process_closure_primitives=true --summary_detail_level=3 --warning_level=VERBOSE --emit_use_strict=true --output_manifest=log/manifest.log --output_module_dependencies=log/module_dependencies.log --property_renaming_report=log/renaming_report.log --js='flexsearch.js' --js_output_file='flexsearch.min.js' && echo Build Complete. && exit 0",
|
||||
"test-production": "nyc --reporter=html --reporter=text mocha --timeout=3000 test --exit",
|
||||
"test-develop": "nyc --reporter=html --reporter=text mocha --timeout=3000 --exit",
|
||||
"test-browser": "mocha-phantomjs test/index.html",
|
||||
"test": "npm run test-develop && npm run test-production && npm run test-browser",
|
||||
"update": "node_modules/.bin/updtr --to non-breaking",
|
||||
"coverage": "nyc report --reporter=lcov --reporter=text-lcov | coveralls"
|
||||
},
|
||||
"files": [
|
||||
"flexsearch.js",
|
||||
"flexsearch.min.js",
|
||||
"test/"
|
||||
],
|
||||
"homepage": "https://nextapps-de.github.io/xone/",
|
||||
"author": "Thomas Wilkerling",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"chai": "^4.1.2",
|
||||
"coveralls": "^3.0.0",
|
||||
"google-closure-compiler": "^20180204.0.0",
|
||||
"mocha": "^5.0.4",
|
||||
"mocha-lcov-reporter": "^1.3.0",
|
||||
"mocha-phantomjs": "^4.1.0",
|
||||
"nyc": "^11.6.0",
|
||||
"phantomjs-prebuilt": "^2.1.16",
|
||||
"updtr": "^2.0.0"
|
||||
}
|
||||
}
|
35
test/index.html
Normal file
35
test/index.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" media="all" href="../node_modules/mocha/mocha.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"><p><a href=".">Index</a></p></div>
|
||||
<div id="messages"></div>
|
||||
<div id="fixtures"></div>
|
||||
<script src="../node_modules/mocha/mocha.js"></script>
|
||||
<script src="../node_modules/chai/chai.js"></script>
|
||||
<!--<script src="../node_modules/mocha-phantomjs-core/browser-shim.js"></script>-->
|
||||
<script src="../flexsearch.min.js"></script>
|
||||
<script>
|
||||
window.initMochaPhantomJS && initMochaPhantomJS();
|
||||
mocha.ui('bdd');
|
||||
mocha.reporter('html');
|
||||
mocha.setup('bdd');
|
||||
var expect = chai.expect;
|
||||
</script>
|
||||
<script src="../test/test.js"></script>
|
||||
<script>
|
||||
if(window.mochaPhantomJS) {
|
||||
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else{
|
||||
|
||||
mocha.run();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1065
test/test.js
Normal file
1065
test/test.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user