mirror of
https://github.com/nextapps-de/flexsearch.git
synced 2025-09-02 18:33:17 +02:00
ADD v0.7.0 (preview)
This commit is contained in:
@@ -1,555 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Benchmark Presets</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
button{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Document Index Benchmark Comparison</h2>
|
||||
<h4>Indexed Text: Movie Documents</h4>
|
||||
<hr>
|
||||
<div id="container"></div>
|
||||
<hr>
|
||||
<script src="../dist/flexsearch.min.js"></script>
|
||||
<script src="../data/movies.js"></script>
|
||||
<script>
|
||||
|
||||
(function(){
|
||||
|
||||
var index = {};
|
||||
var index_doc = {};
|
||||
var flexsearch_doc;
|
||||
var flexsearch_doc_field;
|
||||
var flexsearch_where;
|
||||
var flexsearch_where_custom;
|
||||
var flexsearch_tag;
|
||||
var flexsearch_static;
|
||||
var flexsearch_static_tag;
|
||||
var flexsearch_static_tag_query;
|
||||
var flexsearch_static_query;
|
||||
var flexsearch_index_tag;
|
||||
var flexsearch_index_ref;
|
||||
var flexsearch_find;
|
||||
|
||||
function add(id, cat, content){
|
||||
(index[cat] || (
|
||||
index[cat] = new FlexSearch("fast")
|
||||
)).add(id, content);
|
||||
}
|
||||
|
||||
function search(cat, query){
|
||||
return index[cat].search(query);
|
||||
}
|
||||
|
||||
function add_doc(cat, content){
|
||||
(index_doc[cat] || (
|
||||
index_doc[cat] = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc: {
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
})
|
||||
)).add(content);
|
||||
}
|
||||
|
||||
function search_doc(cat, query){
|
||||
return index_doc[cat].search(query, {
|
||||
field: "title"
|
||||
});
|
||||
}
|
||||
|
||||
var tests = {
|
||||
|
||||
"helper-no-doc": {
|
||||
|
||||
init: function(){},
|
||||
add: function(content){
|
||||
|
||||
add(content.id, content.genre, content.title);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return search("Adventure", query);
|
||||
},
|
||||
loops: 400000
|
||||
},
|
||||
|
||||
"helper-doc": {
|
||||
|
||||
init: function(){},
|
||||
add: function(content){
|
||||
|
||||
add_doc(content.genre, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return search_doc("Adventure", query);
|
||||
},
|
||||
loops: 300000
|
||||
},
|
||||
|
||||
"doc-no-cat-no-field": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_doc = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc: {
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_doc.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_doc.search(query);
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"doc-no-cat-field": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_doc_field = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc: {
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_doc_field.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_doc_field.search(query, {
|
||||
field: "title"
|
||||
});
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"where-cat": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_where = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_where.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_where.search(query, {
|
||||
field: "title",
|
||||
where: {
|
||||
genre: "Adventure"
|
||||
}
|
||||
});
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"where-custom": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_where_custom = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_where_custom.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_where_custom.search(query, {
|
||||
field: "title",
|
||||
where: function(val){
|
||||
return val.genre === "Adventure";
|
||||
}
|
||||
});
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"where-tag": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_tag = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: ["title"],
|
||||
tag: ["genre"]
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_tag.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_tag.search(query, {
|
||||
field: "title",
|
||||
where: {
|
||||
genre: "Adventure"
|
||||
}
|
||||
});
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"where-indexed-manual": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_index_ref = new FlexSearch({
|
||||
encode: false,
|
||||
tokenize: function(doc){
|
||||
return [doc];
|
||||
},
|
||||
doc:{
|
||||
id: "id",
|
||||
field: ["genre"]
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_index_ref.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_index_ref.search("Adventure", {
|
||||
|
||||
field: "genre"
|
||||
});
|
||||
},
|
||||
loops: 300000
|
||||
},
|
||||
|
||||
/*
|
||||
"where-indexed-tag": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_index_tag = new FlexSearch({
|
||||
preset: "fastest",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: ["title"],
|
||||
tag: ["genre"]
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_index_tag.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_index_tag.search("Adventure", {
|
||||
|
||||
field: "genre"
|
||||
});
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
*/
|
||||
|
||||
"static-where": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_static = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_static.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_static.where({
|
||||
|
||||
genre: "Adventure"
|
||||
});
|
||||
},
|
||||
loops: 400
|
||||
},
|
||||
|
||||
"static-where-tag": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_static_tag = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title",
|
||||
tag: "genre"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_static_tag.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_static_tag.where({
|
||||
|
||||
genre: "Adventure"
|
||||
});
|
||||
},
|
||||
loops: 5000000
|
||||
},
|
||||
|
||||
"static-where-query": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_static_query = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_static_query.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_static_query.where({
|
||||
|
||||
title: query,
|
||||
genre: "Adventure"
|
||||
});
|
||||
},
|
||||
loops: 400
|
||||
},
|
||||
|
||||
"static-where-tag-query": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_static_tag_query = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title",
|
||||
tag: "genre"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_static_tag_query.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_static_tag_query.where({
|
||||
|
||||
title: query,
|
||||
genre: "Adventure"
|
||||
});
|
||||
},
|
||||
loops: 5000
|
||||
},
|
||||
|
||||
"static-find-id": {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_find = new FlexSearch({
|
||||
preset: "fast",
|
||||
doc:{
|
||||
id: "id",
|
||||
field: "title"
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(content){
|
||||
|
||||
flexsearch_find.add(content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_find.find(10000);
|
||||
},
|
||||
loops: 20000000
|
||||
}
|
||||
};
|
||||
|
||||
function init_container(target){
|
||||
|
||||
var html = "<table>" +
|
||||
"<tr>" +
|
||||
"<th>Preset </th>" +
|
||||
"<th>Single Phrase </th>" +
|
||||
"<th>Multi Phrase </th>" +
|
||||
"<th>Not Found </th>" +
|
||||
"</tr>";
|
||||
|
||||
for(var test in tests){
|
||||
|
||||
if(tests.hasOwnProperty(test)){
|
||||
|
||||
html += "<tr>" +
|
||||
"<td>" + test + "</td>" +
|
||||
"<td id=\"test-" + test + "\">indexing ...</td>" +
|
||||
"<td id=\"test-multi-" + test + "\"></td>" +
|
||||
"<td id=\"test-notfound-" + test + "\"></td>" +
|
||||
"</tr>"
|
||||
}
|
||||
}
|
||||
|
||||
html += "</table>";
|
||||
|
||||
target.innerHTML = html;
|
||||
}
|
||||
|
||||
var is_mobile = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/);
|
||||
var genres = ["Comedy", "Adventure", "Comic", "Horror"];
|
||||
|
||||
function init_tests(index, keys){
|
||||
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
|
||||
test.init();
|
||||
|
||||
if(is_mobile && (test.loops > 1)){
|
||||
|
||||
test.loops = (test.loops / 5) >> 0;
|
||||
}
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
|
||||
test.add({
|
||||
id: i,
|
||||
genre: genres[i % 4],
|
||||
title: data[i]
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("test-" + key).textContent = "ready ...";
|
||||
|
||||
if(++index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(index, keys);
|
||||
|
||||
}, 100);
|
||||
}
|
||||
else{
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(0, 0, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function start_tests(suite, index, keys){
|
||||
|
||||
var phrase = suite === 0 ? "mermaid" : (suite === 1 ? "little mermaid" : "undefined");
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
var loops = test.loops;
|
||||
var query = test.query;
|
||||
var start = Date.now();
|
||||
|
||||
for(var x = 0; x < loops; x++){
|
||||
|
||||
query(phrase);
|
||||
}
|
||||
|
||||
var duration = Date.now() - start;
|
||||
|
||||
console.log("[Suite " + suite + "] " + key + ":", duration);
|
||||
|
||||
document.getElementById("test-" + (suite === 1 ? "multi-" : (suite === 2 ? "notfound-" : "")) + key).textContent = format_number(((1000 / duration * loops * 10 + 0.5) >> 0) / 10) + " op/s";
|
||||
|
||||
if(++index >= keys.length){
|
||||
|
||||
if(++suite < 3){
|
||||
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(suite, index, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
init_container(document.getElementById("container"));
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(0, Object.keys(tests));
|
||||
|
||||
}, 100);
|
||||
|
||||
function format_number(num){
|
||||
|
||||
return ("" + num).replace(/(\d)(?=(\d{3})+\b)/g, '$1,');
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
//window.tests = tests;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,275 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Benchmark Presets</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
button{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Presets Benchmark Comparison</h2>
|
||||
<h4>Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)</h4>
|
||||
<hr>
|
||||
<div id="container"></div>
|
||||
<hr>
|
||||
<script src="../dist/flexsearch.compact.js"></script>
|
||||
<script src="../data/gulliver.js"></script>
|
||||
<script>
|
||||
|
||||
(function(){
|
||||
|
||||
var flexsearch_default = new FlexSearch();
|
||||
var flexsearch_memory = new FlexSearch("memory");
|
||||
var flexsearch_speed = new FlexSearch("speed");
|
||||
var flexsearch_fast = new FlexSearch("fast");
|
||||
var flexsearch_match = new FlexSearch("match");
|
||||
var flexsearch_score = new FlexSearch("score");
|
||||
var flexsearch_balance = new FlexSearch("balance");
|
||||
|
||||
var tests = {
|
||||
|
||||
"fast": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_fast.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_fast.search(query);
|
||||
},
|
||||
loops: 250000
|
||||
},
|
||||
|
||||
"speed": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_speed.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_speed.search(query);
|
||||
},
|
||||
loops: 150000
|
||||
},
|
||||
|
||||
"default": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_default.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_default.search(query);
|
||||
},
|
||||
loops: 100000
|
||||
},
|
||||
|
||||
"balance": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_balance.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_balance.search(query);
|
||||
},
|
||||
loops: 75000
|
||||
},
|
||||
|
||||
"memory": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_memory.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_memory.search(query);
|
||||
},
|
||||
loops: 20000
|
||||
},
|
||||
|
||||
"match": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_match.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_match.search(query);
|
||||
},
|
||||
loops: 20000
|
||||
},
|
||||
|
||||
"score": {
|
||||
|
||||
init: function(){},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_score.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_score.search(query);
|
||||
},
|
||||
loops: 30000
|
||||
}
|
||||
};
|
||||
|
||||
function init_container(target){
|
||||
|
||||
var html = "<table>" +
|
||||
"<tr>" +
|
||||
"<th>Preset </th>" +
|
||||
"<th>Benchmark (Single Phrase) </th>" +
|
||||
"<th>Benchmark (Multi Phrase) </th>" +
|
||||
"<th>Benchmark (Not Found) </th>" +
|
||||
"</tr>";
|
||||
|
||||
for(var test in tests){
|
||||
|
||||
if(tests.hasOwnProperty(test)){
|
||||
|
||||
html += "<tr>" +
|
||||
"<td>" + test + "</td>" +
|
||||
"<td id=\"test-" + test + "\">indexing ...</td>" +
|
||||
"<td id=\"test-multi-" + test + "\"></td>" +
|
||||
"<td id=\"test-notfound-" + test + "\"></td>" +
|
||||
"</tr>"
|
||||
}
|
||||
}
|
||||
|
||||
html += "</table>";
|
||||
|
||||
target.innerHTML = html;
|
||||
}
|
||||
|
||||
var is_mobile = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/);
|
||||
|
||||
function init_tests(index, keys){
|
||||
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
|
||||
test.init();
|
||||
|
||||
if(is_mobile && (test.loops > 1)){
|
||||
|
||||
test.loops = (test.loops / 5) >> 0;
|
||||
}
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
|
||||
test.add(i, text_data[i]);
|
||||
}
|
||||
|
||||
document.getElementById("test-" + key).textContent = "ready ...";
|
||||
|
||||
if(++index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(index, keys);
|
||||
|
||||
}, 100);
|
||||
}
|
||||
else{
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(0, 0, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
var text_queries_notfound = [
|
||||
|
||||
"undefined1 undefined2 undefined3",
|
||||
"undefined"
|
||||
];
|
||||
|
||||
function start_tests(suite, index, keys){
|
||||
|
||||
var queries = suite === 0 ? text_queries : (suite === 1 ? text_queries_multi : text_queries_notfound);
|
||||
var len = queries.length;
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
var loops = test.loops;
|
||||
var query = test.query;
|
||||
var start = Date.now();
|
||||
|
||||
for(var i = 0; i < len; i++){
|
||||
|
||||
var phrase = queries[i];
|
||||
|
||||
for(var x = 0; x < loops; x++){
|
||||
|
||||
query(phrase);
|
||||
}
|
||||
}
|
||||
|
||||
var duration = Date.now() - start;
|
||||
|
||||
console.log("[Suite " + suite + "] " + key + ":", duration);
|
||||
|
||||
document.getElementById("test-" + (suite === 1 ? "multi-" : (suite === 2 ? "notfound-" : "")) + key).textContent = format_number(((1000 / duration * loops * 10 + 0.5) >> 0) / 10) + " op/s";
|
||||
|
||||
if(++index >= keys.length){
|
||||
|
||||
if(++suite < 3){
|
||||
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(suite, index, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
init_container(document.getElementById("container"));
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(0, Object.keys(tests));
|
||||
|
||||
}, 100);
|
||||
|
||||
function format_number(num){
|
||||
|
||||
return ("" + num).replace(/(\d)(?=(\d{3})+\b)/g, '$1,');
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
//window.tests = tests;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,479 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Benchmark</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
button{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Benchmark Comparison</h2>
|
||||
<h4>Indexed Text: Movie Titles</h4>
|
||||
<hr>
|
||||
<div id="container"></div>
|
||||
<hr>
|
||||
Test rules: 1. no cache allowed, 2. no async allowed, 3. should return at least 8 matches for the query "The Spirit", 4. result should be ordered by relevance
|
||||
<script src="../dist/flexsearch.light.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/bulksearch@master/bulksearch.light.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/weixsong/elasticlunr.js@0.9.6/example/elasticlunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr@2.3.5/lunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/kbrsh/wade@0.3.3/dist/wade.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/krisk/Fuse@3.3.0/dist/fuse.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-search@1.4.2/dist/umd/js-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/BitSet.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/JSii.js"></script>
|
||||
<script src="https://gistcdn.githack.com/vlad-x/a25e0c5c1eeb6bf6aa38/raw/02d1a1703e4a99a7c733c85097f583579f6af4e2/bm25.js"></script>
|
||||
<script src="https://rawcdn.githack.com/jeancroy/FuzzySearch/cbcdd8307d70a209b1cbf17a535158d5c21840d7/dist/FuzzySearch.min.js"></script>
|
||||
<script src="../data/movies.js"></script>
|
||||
<script>
|
||||
|
||||
(function(){
|
||||
|
||||
var bulksearch;
|
||||
var flexsearch;
|
||||
// var flexsearch_cache;
|
||||
// var flexsearch_worker;
|
||||
// var flexsearch_cache_scale;
|
||||
var elasticsearch;
|
||||
var lunrsearch;
|
||||
var wade;
|
||||
var fuse;
|
||||
var jssearch;
|
||||
var jsii;
|
||||
var bm25;
|
||||
var fuzzysearch;
|
||||
|
||||
var tests = {
|
||||
|
||||
flexsearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 8,
|
||||
resolution: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: false,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch.search(query);
|
||||
},
|
||||
loops: 350000
|
||||
},
|
||||
|
||||
/*
|
||||
flexsearch_cache_unbound: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_cache = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: true,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_cache.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_cache.search(query);
|
||||
},
|
||||
loops: 1000000
|
||||
},
|
||||
*/
|
||||
|
||||
/*
|
||||
flexsearch_cache_balanced: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_cache_scale = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: 100,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_cache_scale.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_cache_scale.search(query);
|
||||
},
|
||||
loops: 1000000
|
||||
},
|
||||
*/
|
||||
|
||||
/*
|
||||
flexsearch_worker: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_worker = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: true,
|
||||
cache: false,
|
||||
worker: 4
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_worker.add(index, content);
|
||||
},
|
||||
query: async function(query){
|
||||
|
||||
return await new Promise(function(resolve){
|
||||
|
||||
flexsearch_worker.search(query, resolve);
|
||||
});
|
||||
},
|
||||
loops: 5000
|
||||
},
|
||||
*/
|
||||
|
||||
bulksearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
bulksearch = new BulkSearch({
|
||||
type: "short",
|
||||
encode: "icase",
|
||||
multi: false,
|
||||
async: false,
|
||||
cache: false,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
bulksearch.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return bulksearch.search(query);
|
||||
},
|
||||
loops: 2800
|
||||
},
|
||||
|
||||
elasticlunr: {
|
||||
|
||||
init: function(){
|
||||
|
||||
elasticsearch = elasticlunr(function(){
|
||||
this.setRef("id");
|
||||
this.addField("content");
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
elasticsearch.addDoc({id: index, content: content});
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return elasticsearch.search(query);
|
||||
},
|
||||
loops: 700
|
||||
},
|
||||
|
||||
lunr: {
|
||||
|
||||
init: function(){
|
||||
|
||||
lunrsearch = lunr(function(){
|
||||
this.ref("id");
|
||||
this.field("content");
|
||||
for(var i = 0; i < data.length; i++){
|
||||
this.add({id: i, content: data[i]});
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return lunrsearch.search(query);
|
||||
},
|
||||
loops: 2400
|
||||
},
|
||||
|
||||
wade: {
|
||||
|
||||
init: function(){
|
||||
|
||||
wade = Wade(data.slice(0));
|
||||
},
|
||||
sort: function(a, b){
|
||||
|
||||
var sum = a.score - b.score;
|
||||
return sum < 0 ? 1 : sum ? -1 : 0;
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return wade(query).sort(this.sort);
|
||||
},
|
||||
loops: 10000
|
||||
},
|
||||
|
||||
fuse: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
payload[i] = {id: i, content: data[i]};
|
||||
}
|
||||
|
||||
fuse = new Fuse(payload, {
|
||||
keys: ["content"],
|
||||
id: "id",
|
||||
shouldSort: true,
|
||||
tokenize: true,
|
||||
matchAllTokens: true,
|
||||
threshold: 0.2
|
||||
});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return fuse.search(query);
|
||||
},
|
||||
loops: 1
|
||||
},
|
||||
|
||||
jssearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
payload[i] = {id: i, content: data[i]};
|
||||
}
|
||||
|
||||
jssearch = new JsSearch.Search("id");
|
||||
jssearch.addIndex("content");
|
||||
jssearch.addDocuments(payload);
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return jssearch.search(query);
|
||||
},
|
||||
loops: 8000
|
||||
},
|
||||
|
||||
jsii: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
payload[i] = {id: i, text: data[i]};
|
||||
}
|
||||
|
||||
jsii = new JSii();
|
||||
jsii.feedDocs(payload);
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return jsii.search(query);
|
||||
},
|
||||
loops: 100000
|
||||
},
|
||||
|
||||
bm25: {
|
||||
|
||||
init: function(){
|
||||
|
||||
bm25 = new BM25();
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
bm25.addDocument({id: i, body: data[i]});
|
||||
}
|
||||
|
||||
bm25.updateIdf();
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return bm25.search(query);
|
||||
},
|
||||
loops: 50
|
||||
},
|
||||
|
||||
fuzzysearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
fuzzysearch = new FuzzySearch({source:data.slice(0)});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return fuzzysearch.search(query);
|
||||
},
|
||||
loops: 4
|
||||
}
|
||||
};
|
||||
|
||||
function init_container(target){
|
||||
|
||||
var html = "<table>" +
|
||||
"<tr>" +
|
||||
"<th>Library </th>" +
|
||||
"<th>Benchmark (Single Phrase) </th>" +
|
||||
"<th>Benchmark (Multi Phrase) </th>" +
|
||||
"<th>Benchmark (Not Found) </th>" +
|
||||
"</tr>";
|
||||
|
||||
for(var test in tests){
|
||||
|
||||
if(tests.hasOwnProperty(test)){
|
||||
|
||||
html += "<tr>" +
|
||||
"<td>" + test + "</td>" +
|
||||
"<td id=\"test-" + test + "\">indexing ...</td>" +
|
||||
"<td id=\"test-multi-" + test + "\"></td>" +
|
||||
"<td id=\"test-notfound-" + test + "\"></td>" +
|
||||
"</tr>"
|
||||
}
|
||||
}
|
||||
|
||||
html += "</table>";
|
||||
|
||||
target.innerHTML = html;
|
||||
}
|
||||
|
||||
var is_mobile = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/);
|
||||
|
||||
function init_tests(index, keys){
|
||||
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
|
||||
test.init();
|
||||
|
||||
if(is_mobile && (test.loops > 1)){
|
||||
|
||||
test.loops = (test.loops / 5) >> 0;
|
||||
}
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
|
||||
test.add(i, data[i]);
|
||||
}
|
||||
|
||||
document.getElementById("test-" + key).textContent = "ready ...";
|
||||
|
||||
if(++index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(index, keys);
|
||||
|
||||
}, 100);
|
||||
}
|
||||
else{
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(0, 0, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function start_tests(suite, index, keys){
|
||||
|
||||
var phrase = suite === 0 ? "mermaid" : (suite === 1 ? "little mermaid" : "undefined");
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
var loops = test.loops;
|
||||
var query = test.query;
|
||||
var start = Date.now();
|
||||
|
||||
for(var x = 0; x < loops; x++){
|
||||
|
||||
query(phrase);
|
||||
}
|
||||
|
||||
var duration = Date.now() - start;
|
||||
|
||||
console.log("[Suite " + suite + "] " + key + ":", duration);
|
||||
|
||||
document.getElementById("test-" + (suite === 1 ? "multi-" : (suite === 2 ? "notfound-" : "")) + key).textContent = format_number(((1000 / duration * loops * 10 + 0.5) >> 0) / 10) + " op/s";
|
||||
|
||||
if(++index >= keys.length){
|
||||
|
||||
if(++suite < 3){
|
||||
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(suite, index, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
init_container(document.getElementById("container"));
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(0, Object.keys(tests));
|
||||
|
||||
}, 100);
|
||||
|
||||
function format_number(num){
|
||||
|
||||
return ("" + num).replace(/(\d)(?=(\d{3})+\b)/g, '$1,');
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
//window.tests = tests;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,487 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Benchmark</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
button{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Benchmark Comparison</h2>
|
||||
<h4>Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)</h4>
|
||||
<hr>
|
||||
<div id="container"></div>
|
||||
<hr>
|
||||
Test rules: 1. no cache allowed, 2. no async allowed, 3. should return at least 7 matches for the query "gulliver", 4. result should be ordered by relevance
|
||||
<script src="../dist/flexsearch.light.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/bulksearch@master/bulksearch.light.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/weixsong/elasticlunr.js@0.9.6/example/elasticlunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr@2.3.5/lunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/kbrsh/wade@0.3.3/dist/wade.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/krisk/Fuse@3.3.0/dist/fuse.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-search@1.4.2/dist/umd/js-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/BitSet.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/JSii.js"></script>
|
||||
<script src="https://gistcdn.githack.com/vlad-x/a25e0c5c1eeb6bf6aa38/raw/02d1a1703e4a99a7c733c85097f583579f6af4e2/bm25.js"></script>
|
||||
<script src="https://rawcdn.githack.com/jeancroy/FuzzySearch/cbcdd8307d70a209b1cbf17a535158d5c21840d7/dist/FuzzySearch.min.js"></script>
|
||||
<script src="../data/gulliver.js"></script>
|
||||
<script>
|
||||
|
||||
(function(){
|
||||
|
||||
var bulksearch;
|
||||
var flexsearch;
|
||||
var flexsearch_cache;
|
||||
var flexsearch_worker;
|
||||
var flexsearch_cache_scale;
|
||||
var elasticsearch;
|
||||
var lunrsearch;
|
||||
var wade;
|
||||
var fuse;
|
||||
var jssearch;
|
||||
var jsii;
|
||||
var bm25;
|
||||
var fuzzysearch;
|
||||
|
||||
var tests = {
|
||||
|
||||
flexsearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 8,
|
||||
resolution: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: false,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch.search(query);
|
||||
},
|
||||
loops: 275000
|
||||
},
|
||||
|
||||
/*
|
||||
flexsearch_cache_unbound: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_cache = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: true,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_cache.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_cache.search(query);
|
||||
},
|
||||
loops: 1000000
|
||||
},
|
||||
|
||||
flexsearch_cache_balanced: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_cache_scale = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: false,
|
||||
cache: 100,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_cache_scale.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return flexsearch_cache_scale.search(query);
|
||||
},
|
||||
loops: 1000000
|
||||
},
|
||||
|
||||
flexsearch_worker: {
|
||||
|
||||
init: function(){
|
||||
|
||||
flexsearch_worker = new FlexSearch({
|
||||
encode: "icase",
|
||||
tokenize: "strict",
|
||||
threshold: 9,
|
||||
depth: 1,
|
||||
async: true,
|
||||
cache: false,
|
||||
worker: 4
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
flexsearch_worker.add(index, content);
|
||||
},
|
||||
query: async function(query){
|
||||
|
||||
return await new Promise(function(resolve){
|
||||
|
||||
flexsearch_worker.search(query, resolve);
|
||||
});
|
||||
},
|
||||
loops: 5000
|
||||
},
|
||||
*/
|
||||
|
||||
bulksearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
bulksearch = new BulkSearch({
|
||||
type: "short",
|
||||
encode: "icase",
|
||||
multi: false,
|
||||
async: false,
|
||||
cache: false,
|
||||
worker: false
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
bulksearch.add(index, content);
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return bulksearch.search(query);
|
||||
},
|
||||
loops: 250
|
||||
},
|
||||
|
||||
elasticlunr: {
|
||||
|
||||
init: function(){
|
||||
|
||||
elasticsearch = elasticlunr(function(){
|
||||
this.setRef("id");
|
||||
this.addField("content");
|
||||
});
|
||||
},
|
||||
add: function(index, content){
|
||||
|
||||
elasticsearch.addDoc({id: index, content: content});
|
||||
},
|
||||
query: function(query){
|
||||
|
||||
return elasticsearch.search(query);
|
||||
},
|
||||
loops: 100
|
||||
},
|
||||
|
||||
lunr: {
|
||||
|
||||
init: function(){
|
||||
|
||||
lunrsearch = lunr(function(){
|
||||
this.ref("id");
|
||||
this.field("content");
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
this.add({id: i, content: text_data[i]});
|
||||
}
|
||||
});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return lunrsearch.search(query);
|
||||
},
|
||||
loops: 350
|
||||
},
|
||||
|
||||
wade: {
|
||||
|
||||
init: function(){
|
||||
|
||||
wade = Wade(text_data.slice(0));
|
||||
},
|
||||
sort: function(a, b){
|
||||
|
||||
var sum = a.score - b.score;
|
||||
return sum < 0 ? 1 : sum ? -1 : 0;
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return wade(query).sort(this.sort);
|
||||
},
|
||||
loops: 1500
|
||||
},
|
||||
|
||||
fuse: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
payload[i] = {id: i, content: text_data[i]};
|
||||
}
|
||||
|
||||
fuse = new Fuse(payload, {
|
||||
keys: ["content"],
|
||||
id: "id",
|
||||
shouldSort: true,
|
||||
tokenize: true,
|
||||
matchAllTokens: true,
|
||||
threshold: 0.2
|
||||
});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return fuse.search(query);
|
||||
},
|
||||
loops: 1
|
||||
},
|
||||
|
||||
jssearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
payload[i] = {id: i, content: text_data[i]};
|
||||
}
|
||||
|
||||
jssearch = new JsSearch.Search("id");
|
||||
jssearch.addIndex("content");
|
||||
jssearch.addDocuments(payload);
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return jssearch.search(query);
|
||||
},
|
||||
loops: 800
|
||||
},
|
||||
|
||||
jsii: {
|
||||
|
||||
init: function(){
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
payload[i] = {id: i, text: text_data[i]};
|
||||
}
|
||||
|
||||
jsii = new JSii();
|
||||
jsii.feedDocs(payload);
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return jsii.search(query);
|
||||
},
|
||||
loops: 600
|
||||
},
|
||||
|
||||
bm25: {
|
||||
|
||||
init: function(){
|
||||
|
||||
bm25 = new BM25();
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
bm25.addDocument({id: i, body: text_data[i]});
|
||||
}
|
||||
|
||||
bm25.updateIdf();
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return bm25.search(query);
|
||||
},
|
||||
loops: 95
|
||||
},
|
||||
|
||||
fuzzysearch: {
|
||||
|
||||
init: function(){
|
||||
|
||||
fuzzysearch = new FuzzySearch({source:text_data.slice(0)});
|
||||
},
|
||||
add: function(index, content){},
|
||||
query: function(query){
|
||||
|
||||
return fuzzysearch.search(query);
|
||||
},
|
||||
loops: 4
|
||||
}
|
||||
};
|
||||
|
||||
function init_container(target){
|
||||
|
||||
var html = "<table>" +
|
||||
"<tr>" +
|
||||
"<th>Library </th>" +
|
||||
"<th>Benchmark (Single Phrase) </th>" +
|
||||
"<th>Benchmark (Multi Phrase) </th>" +
|
||||
"<th>Benchmark (Not Found) </th>" +
|
||||
"</tr>";
|
||||
|
||||
for(var test in tests){
|
||||
|
||||
if(tests.hasOwnProperty(test)){
|
||||
|
||||
html += "<tr>" +
|
||||
"<td>" + test + "</td>" +
|
||||
"<td id=\"test-" + test + "\">indexing ...</td>" +
|
||||
"<td id=\"test-multi-" + test + "\"></td>" +
|
||||
"<td id=\"test-notfound-" + test + "\"></td>" +
|
||||
"</tr>"
|
||||
}
|
||||
}
|
||||
|
||||
html += "</table>";
|
||||
|
||||
target.innerHTML = html;
|
||||
}
|
||||
|
||||
var is_mobile = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/);
|
||||
|
||||
function init_tests(index, keys){
|
||||
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
|
||||
test.init();
|
||||
|
||||
if(is_mobile){
|
||||
|
||||
test.loops = Math.max((test.loops / 5) >> 0, 1);
|
||||
}
|
||||
|
||||
for(var i = 0; i < text_data.length; i++){
|
||||
|
||||
test.add(i, text_data[i]);
|
||||
}
|
||||
|
||||
document.getElementById("test-" + key).textContent = "ready ...";
|
||||
|
||||
if(++index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(index, keys);
|
||||
|
||||
}, 100);
|
||||
}
|
||||
else{
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(0, 0, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
var text_queries_notfound = [
|
||||
|
||||
"undefined1 undefined2 undefined3",
|
||||
"undefined"
|
||||
];
|
||||
|
||||
function start_tests(suite, index, keys){
|
||||
|
||||
var queries = suite === 0 ? text_queries : (suite === 1 ? text_queries_multi : text_queries_notfound);
|
||||
var len = queries.length;
|
||||
var key = keys[index];
|
||||
var test = tests[key];
|
||||
var loops = test.loops;
|
||||
var query = test.query;
|
||||
var start = Date.now();
|
||||
|
||||
for(var i = 0; i < len; i++){
|
||||
|
||||
var phrase = queries[i];
|
||||
|
||||
for(var x = 0; x < loops; x++){
|
||||
|
||||
query(phrase);
|
||||
}
|
||||
}
|
||||
|
||||
var duration = Date.now() - start;
|
||||
|
||||
console.log("[Suite " + suite + "] " + key + ":", duration);
|
||||
|
||||
document.getElementById("test-" + (suite === 1 ? "multi-" : (suite === 2 ? "notfound-" : "")) + key).textContent = format_number(((1000 / duration * loops * 10 + 0.5) >> 0) / 10) + " op/s";
|
||||
|
||||
if(++index >= keys.length){
|
||||
|
||||
if(++suite < 3){
|
||||
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(index < keys.length){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
start_tests(suite, index, keys);
|
||||
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
init_container(document.getElementById("container"));
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
init_tests(0, Object.keys(tests));
|
||||
|
||||
}, 100);
|
||||
|
||||
function format_number(num){
|
||||
|
||||
return ("" + num).replace(/(\d)(?=(\d{3})+\b)/g, '$1,');
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
//window.tests = tests;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -3,16 +3,33 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" media="all" href="../node_modules/mocha/mocha.css">
|
||||
<link rel="stylesheet" media="all" href="node_modules/mocha/mocha.css">
|
||||
<style>
|
||||
body{
|
||||
background-color: #151515;
|
||||
filter: invert(1);
|
||||
}
|
||||
</style>
|
||||
</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>
|
||||
var param = window.location.search.substr(1);
|
||||
if(param === "coverage"){
|
||||
document.write('<script type="text/javascript" src="dist/dist/flexsearch.pre.js"><\/script>');
|
||||
}
|
||||
else if(param === "es5" || param === "light" || param === "min"){
|
||||
document.write('<script type="text/javascript" src="../dist/flexsearch.' + param + '.js"><\/script>');
|
||||
}
|
||||
else{
|
||||
document.write('<script type="text/javascript" src="dist/flexsearch.pre.js"><\/script>');
|
||||
}
|
||||
</script>
|
||||
<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="../dist/flexsearch.es5.js"></script>
|
||||
<script>
|
||||
window.initMochaPhantomJS && initMochaPhantomJS();
|
||||
mocha.ui('bdd');
|
||||
|
@@ -1,339 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Presets Scoring Comparison</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Presets Scoring Comparison</h2>
|
||||
<h4>Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)</h4>
|
||||
<hr>
|
||||
<script src="../dist/flexsearch.min.js"></script>
|
||||
<script src="../data/gulliver.js"></script>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<th><b>Query</b></th>
|
||||
<th>default</th>
|
||||
<th>memory</th>
|
||||
<th>speed</th>
|
||||
<th>match</th>
|
||||
<th>score</th>
|
||||
<th>balance</th>
|
||||
<th>fast</th>
|
||||
</tr>
|
||||
<tr id="test-1">
|
||||
<td style="width: 200px">"without breach of modesty"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-2">
|
||||
<td>"went softly stream"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-3">
|
||||
<td>"princes of the ambition"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-4">
|
||||
<td>"five-thousand leagues"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-5">
|
||||
<td>"i already observed"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-6">
|
||||
<td>"let a of his"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-7">
|
||||
<td>"take that to the rocks"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-8">
|
||||
<td>"bignes of splaknuk"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-9">
|
||||
<td>"matematikal musikal instruments"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-10">
|
||||
<td>"matical sical strument"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-11">
|
||||
<td>"lalkon the camberlayhn"</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<div style="line-height: 2em">
|
||||
<div style="display:inline-block; width:16px; height:16px; background: #f00"></div> Either no results or relevant content was not included in results.<br>
|
||||
<div style="display:inline-block; width:16px; height:16px; background: orange"></div> Most relevant results was not found in the first place.<br>
|
||||
<div style="display:inline-block; width:16px; height:16px; background: #0a0"></div> Most relevant results was successfully found in the first place.<br>
|
||||
<b>Note:</b> Open console and type e.g. <i>data[493]</i>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
var data = [];
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
var new_data = text_data;
|
||||
var tmp = '';
|
||||
|
||||
for(var i = 0; i < new_data.length; i++){
|
||||
|
||||
if(new_data[i].length > 2) {
|
||||
|
||||
tmp += new_data[i] + '. ';
|
||||
|
||||
if((tmp.length > 1000) || (i === new_data.length - 1)){
|
||||
|
||||
data.push(tmp.replace(/{[^}]*}/g, ''));
|
||||
tmp = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var flexsearch_default = new FlexSearch();
|
||||
var flexsearch_memory = new FlexSearch("memory");
|
||||
var flexsearch_speed = new FlexSearch("speed");
|
||||
var flexsearch_fast = new FlexSearch("fast");
|
||||
var flexsearch_match = new FlexSearch("match");
|
||||
var flexsearch_score = new FlexSearch("score");
|
||||
var flexsearch_balance = new FlexSearch("balance");
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_default');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_default.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_default');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_memory');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_memory.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_memory');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_speed');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_speed.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_speed');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_match');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_match.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_match');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_score');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_score.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_score');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_balance');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_balance.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_balance');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
console.time('flexsearch_fast');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch_fast.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch_fast');
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
do_test('test-1', 'without breach of modesty', [493]);
|
||||
do_test('test-2', 'went softly stream', [446]);
|
||||
do_test('test-3', 'princes of the ambition', [72, 408]);
|
||||
do_test('test-4', 'five-thousand leagues', [2]);
|
||||
do_test('test-5', 'i already observed', [458, 346]);
|
||||
do_test('test-6', 'let a of his', [50]);
|
||||
do_test('test-7', 'take that to the rocks', [175]);
|
||||
do_test('test-8', 'bignes of splaknuk', [146]);
|
||||
do_test('test-9', 'matematikal musikal instruments', [267]);
|
||||
do_test('test-10', 'matical sical strument', [267]);
|
||||
do_test('test-11', 'lalkon the camberlayhn', [99]);
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
function do_test(id, query, ref){
|
||||
|
||||
var nodes = document.getElementById(id).getElementsByTagName('td');
|
||||
|
||||
for(var i = 1; i < nodes.length; i++){
|
||||
|
||||
var results;
|
||||
|
||||
switch(i){
|
||||
|
||||
case 1:
|
||||
results = flexsearch_default.search(query);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
results = flexsearch_memory.search(query);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
results = flexsearch_speed.search(query);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
results = flexsearch_match.search(query);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
results = flexsearch_score.search(query);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
results = flexsearch_balance.search(query);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
results = flexsearch_fast.search(query);
|
||||
break;
|
||||
}
|
||||
|
||||
for(var a = 0; a < ref.length; a++){
|
||||
|
||||
var current = ref[a];
|
||||
|
||||
nodes[i].innerHTML = results[0] || '-';
|
||||
nodes[i].style.color = '#fff';
|
||||
|
||||
if((results[0] === current) || (results[0] === String(current))){
|
||||
|
||||
nodes[i].style.backgroundColor = '#0a0';
|
||||
break;
|
||||
}
|
||||
else if(!results.length || ((results.indexOf(current) === -1) && (results.indexOf(String(current)) === -1))){
|
||||
|
||||
if(nodes[i].style.backgroundColor !== 'orange'){
|
||||
|
||||
nodes[i].style.backgroundColor = '#f00';
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
nodes[i].style.backgroundColor = 'orange';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 50);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,528 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Matching Test</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table td{
|
||||
padding: 1em 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Relevance Scoring Comparison</h2>
|
||||
<h4>Indexed Text: "Gulliver's Travels" (Swift Jonathan 1726)</h4>
|
||||
<hr>
|
||||
<div id="container">
|
||||
<table>
|
||||
<tr>
|
||||
<th><b>Query</b></th>
|
||||
<th>flexsearch</th>
|
||||
<th>bulksearch</th>
|
||||
<th>elasticlunr</th>
|
||||
<th>lunr</th>
|
||||
<th>wade</th>
|
||||
<th>fuse</th>
|
||||
<th>jssearch</th>
|
||||
<th>jsii</th>
|
||||
<th>bm25</th>
|
||||
<th>fuzzysearch</th>
|
||||
</tr>
|
||||
<tr id="test-1">
|
||||
<td style="width: 200px"></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-2">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-3">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-4">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-5">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-6">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-7">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-8">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-9">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-10">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-11">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr id="test-12">
|
||||
<td></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="10">
|
||||
<br>
|
||||
Contextual Search Test:
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="test-13">
|
||||
<td style="width: 200px"></td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
<td>wait ...</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<div style="line-height: 2em">
|
||||
<div style="display:inline-block; width:16px; height:16px; background: #f00"></div> Either no results or relevant content was not included in results.<br>
|
||||
<div style="display:inline-block; width:16px; height:16px; background: orange"></div> Most relevant results was not found in the first place.<br>
|
||||
<div style="display:inline-block; width:16px; height:16px; background: #0a0"></div> Most relevant results was successfully found in the first place.<br>
|
||||
<b>Note:</b> Open console and type e.g. <i>data[493]</i>
|
||||
</div>
|
||||
<script src="../dist/flexsearch.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/nextapps-de/bulksearch@master/bulksearch.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/weixsong/elasticlunr.js@0.9.6/example/elasticlunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr@2.1.6/lunr.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/kbrsh/wade@master/dist/wade.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/krisk/Fuse@3.0.4/dist/fuse.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-search@1.3.7/dist/umd/js-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/BitSet.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/karussell/jsii@master/web/js/src/JSii.js"></script>
|
||||
<script src="https://gistcdn.githack.com/vlad-x/a25e0c5c1eeb6bf6aa38/raw/02d1a1703e4a99a7c733c85097f583579f6af4e2/bm25.js"></script>
|
||||
<script src="https://rawcdn.githack.com/jeancroy/FuzzySearch/cbcdd8307d70a209b1cbf17a535158d5c21840d7/dist/FuzzySearch.min.js"></script>
|
||||
<script src="../data/gulliver.js"></script>
|
||||
<script>
|
||||
|
||||
var data = [];
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
var new_data = text_data;
|
||||
var tmp = '';
|
||||
|
||||
for(var i = 0; i < new_data.length; i++){
|
||||
|
||||
if(new_data[i].length > 2) {
|
||||
|
||||
tmp += new_data[i] + '. ';
|
||||
|
||||
if((tmp.length > 1000) || (i === new_data.length - 1)){
|
||||
|
||||
data.push(tmp.replace(/{[^}]*}/g, ''));
|
||||
tmp = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.push('zero one two three four five six seven eight nine ten.');
|
||||
data.push('zero one two three four five six seven eight nine ten.');
|
||||
data.push('four two zero one three ten five seven eight six nine.');
|
||||
data.push('zero one two three four five six seven eight nine ten.');
|
||||
data.push('zero one two three four five six seven eight nine ten.');
|
||||
|
||||
tmp = null;
|
||||
new_data = null;
|
||||
text_data = null;
|
||||
|
||||
var bulksearch;
|
||||
var flexsearch;
|
||||
var elasticsearch;
|
||||
var lunrsearch;
|
||||
var wade;
|
||||
var fuse;
|
||||
var jssearch;
|
||||
var jsii;
|
||||
var bm25;
|
||||
var fuzzysearch;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
bulksearch = new BulkSearch({
|
||||
type: 'short', // this type specifies the maximum bitlength of assigned IDs!
|
||||
encode: 'extra',
|
||||
multi: true
|
||||
});
|
||||
|
||||
console.time('bulksearch');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
bulksearch.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('bulksearch');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
flexsearch = new FlexSearch({
|
||||
encode: 'extra',
|
||||
tokenize: 'strict',
|
||||
threshold: 0,
|
||||
resolution: 9,
|
||||
depth: 3
|
||||
});
|
||||
|
||||
console.time('flexsearch');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
flexsearch.add(i, data[i]);
|
||||
}
|
||||
|
||||
console.timeEnd('flexsearch');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
elasticsearch = elasticlunr(function () {
|
||||
this.setRef('id');
|
||||
this.addField('content');
|
||||
});
|
||||
|
||||
console.time('elasticsearch');
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
elasticsearch.addDoc({id: i, content: data[i]});
|
||||
}
|
||||
|
||||
console.timeEnd('elasticsearch');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
console.time('lunr');
|
||||
|
||||
lunrsearch = lunr(function(){
|
||||
this.ref('id');
|
||||
this.field('content');
|
||||
for(var i = 0; i < data.length; i++){
|
||||
this.add({id: i, content: data[i]});
|
||||
}
|
||||
});
|
||||
|
||||
console.timeEnd('lunr');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
var wadesearch = function(query){
|
||||
return wade(query).sort(sort_by_score_down);
|
||||
};
|
||||
|
||||
function sort_by_score_down(a, b){
|
||||
var sum = a.score - b.score;
|
||||
return sum < 0 ? 1 : sum > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
console.time('wade');
|
||||
wade = Wade(data.slice(0));
|
||||
console.timeEnd('wade');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
payload[i] = {id: i, content: data[i]};
|
||||
}
|
||||
|
||||
// Note: fuse adds async?
|
||||
console.time('fuse');
|
||||
|
||||
fuse = new Fuse(payload.slice(0), {
|
||||
keys: ['content'],
|
||||
id: 'id',
|
||||
shouldSort: true,
|
||||
threshold: 0.6,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
findAllMatches: true,
|
||||
maxPatternLength: 32,
|
||||
minMatchCharLength: 1
|
||||
});
|
||||
|
||||
console.timeEnd('fuse');
|
||||
|
||||
// payload = null;
|
||||
// data = null;
|
||||
// return;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
jssearch = new JsSearch.Search('id');
|
||||
jssearch.addIndex('content');
|
||||
console.time('jssearch');
|
||||
jssearch.addDocuments(payload.slice(0));
|
||||
console.timeEnd('jssearch');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
var payload = [];
|
||||
|
||||
for(var i = 0; i < data.length; i++){
|
||||
payload[i] = {id: i, text: data[i]};
|
||||
}
|
||||
|
||||
jsii = new JSii();
|
||||
|
||||
console.time('jsii');
|
||||
jsii.feedDocs(payload.slice(0));
|
||||
console.timeEnd('jsii');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
bm25 = new BM25();
|
||||
|
||||
console.time('bm25');
|
||||
for(var i = 0; i < data.length; i++){
|
||||
bm25.addDocument({id: i, body: data[i]});
|
||||
}
|
||||
bm25.updateIdf();
|
||||
console.timeEnd('bm25');
|
||||
|
||||
payload = null;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
console.time('fuzzysearch');
|
||||
fuzzysearch = new FuzzySearch({source:data.slice(0)});
|
||||
console.timeEnd('fuzzysearch');
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
do_test('test-1', 'without breach of modesty', [493]);
|
||||
do_test('test-2', 'went softly stream', [446]);
|
||||
do_test('test-3', 'princes of the ambition', [72, 408]);
|
||||
do_test('test-4', 'five-thousand leagues', [2]);
|
||||
do_test('test-5', 'i already observed', [458, 346]);
|
||||
do_test('test-6', 'disgust the bigness', [175]);
|
||||
do_test('test-7', 'bignes of splaknuk', [146]);
|
||||
do_test('test-8', 'matematikal musikal instruments', [267]);
|
||||
do_test('test-9', 'composition of minerals gums juices vegetables', [303]);
|
||||
do_test('test-10', 'lalkon the camberlayhn', [99]);
|
||||
do_test('test-11', 'to be at all this is', [184]);
|
||||
do_test('test-12', 'matical sical strument', [267]);
|
||||
do_test('test-13', 'zero one three ten', [504]);
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
function do_test(id, query, ref){
|
||||
|
||||
var nodes = document.getElementById(id).getElementsByTagName('td');
|
||||
|
||||
nodes[0].innerHTML = query;
|
||||
|
||||
for(var i = 1; i < nodes.length; i++){
|
||||
|
||||
var results;
|
||||
|
||||
switch(i){
|
||||
|
||||
case 1:
|
||||
results = flexsearch.search(query, {suggest: true});
|
||||
break;
|
||||
|
||||
case 2:
|
||||
results = bulksearch.search(query, {suggest: true});
|
||||
break;
|
||||
|
||||
case 3:
|
||||
results = elasticsearch.search(query).map(function(val){return val.ref});
|
||||
break;
|
||||
|
||||
case 4:
|
||||
results = lunrsearch.search(query).map(function(val){return val.ref});
|
||||
break;
|
||||
|
||||
case 5:
|
||||
results = wadesearch(query).map(function(val){return val.index});
|
||||
break;
|
||||
|
||||
case 6:
|
||||
results = fuse.search(query);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
results = jssearch.search(query).map(function(val){return val.id});
|
||||
break;
|
||||
|
||||
case 8:
|
||||
results = jsii.search(query).docs.map(function(val){return val.id});
|
||||
break;
|
||||
|
||||
case 9:
|
||||
results = bm25.search(query).map(function(val){return val.id});
|
||||
break;
|
||||
|
||||
case 10:
|
||||
results = fuzzysearch.search(query).map(function(val){
|
||||
for(var i = 0; i < data.length; i++){
|
||||
if(val === data[i]) return i;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
for(var a = 0; a < ref.length; a++){
|
||||
|
||||
var current = ref[a];
|
||||
|
||||
nodes[i].innerHTML = results[0] || '-';
|
||||
nodes[i].style.color = '#fff';
|
||||
|
||||
if((results[0] === current) || (results[0] === String(current))){
|
||||
|
||||
nodes[i].style.backgroundColor = '#0a0';
|
||||
break;
|
||||
}
|
||||
else if(!results.length || ((results.indexOf(current) === -1) && (results.indexOf(String(current)) === -1))){
|
||||
|
||||
if(nodes[i].style.backgroundColor !== 'orange'){
|
||||
|
||||
nodes[i].style.backgroundColor = '#f00';
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
nodes[i].style.backgroundColor = 'orange';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 50);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
21
test/merge-coverage.js
Normal file
21
test/merge-coverage.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const libCoverage = require('istanbul-lib-coverage');
|
||||
const { createReporter } = require('istanbul-api');
|
||||
|
||||
const coverage_1 = require('./.nyc_output/coverage.json');
|
||||
const coverage_2 = require('./.nyc_output/coverage2.json');
|
||||
|
||||
const normalizeJestCoverage = (obj) => {
|
||||
const result = obj;
|
||||
Object.entries(result).forEach(([k, v]) => {
|
||||
if (v.data) result[k] = v.data;
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const map = libCoverage.createCoverageMap();
|
||||
map.merge(normalizeJestCoverage(coverage_1));
|
||||
map.merge(normalizeJestCoverage(coverage_2));
|
||||
|
||||
const reporter = createReporter();
|
||||
reporter.addAll(['html', 'json', 'lcov', 'text']);
|
||||
reporter.write(map);
|
50
test/package.json
Normal file
50
test/package.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"public": false,
|
||||
"preferGlobal": false,
|
||||
"scripts": {
|
||||
|
||||
|
||||
"test:production": "mocha --timeout=3000 test --exit",
|
||||
"test:light": "mocha --timeout=3000 test/ --exit",
|
||||
"test:develop": "mocha --timeout=3000 --exit",
|
||||
"test:browser": "nyc instrument ./dist/flexsearch.pre.js ./dist/ && nyc --reporter=html --reporter=text --cache true mocha-headless-chrome -f index.html?coverage -c .nyc_output/coverage.json && mocha-headless-chrome -f polyfill.html?coverage -c .nyc_output/coverage2.json",
|
||||
"test:polyfill": "nyc --reporter=html --reporter=text --cache true mocha-headless-chrome -f polyfill.html?coverage -c .nyc_output/coverage2.json",
|
||||
"test:es5": "mocha-phantomjs index.html",
|
||||
|
||||
|
||||
|
||||
"test": "npm run test:es5 && npm run test:browser && node ./merge-coverage.js",
|
||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||
"server": "node server.js"
|
||||
},
|
||||
"nyc": {
|
||||
"per-file": true,
|
||||
"all": true,
|
||||
"exclude-after-remap": false,
|
||||
"include": [
|
||||
"dist/flexsearch.pre.js"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"dist/",
|
||||
"src/",
|
||||
"task/",
|
||||
"server/",
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"readme": "README.md",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"codacy-coverage": "^3.4.0",
|
||||
"coveralls": "^3.0.7",
|
||||
"istanbul-api": "^2.1.6",
|
||||
"mocha": "^6.2.0",
|
||||
"mocha-headless-chrome": "^2.0.3",
|
||||
"mocha-lcov-reporter": "^1.3.0",
|
||||
"mocha-phantomjs": "^4.1.0",
|
||||
"nyc": "^14.1.1",
|
||||
"web-servo": "^0.5.1"
|
||||
}
|
||||
}
|
61
test/polyfill.html
Normal file
61
test/polyfill.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" media="all" href="node_modules/mocha/mocha.css">
|
||||
<style>
|
||||
body{
|
||||
background-color: #151515;
|
||||
filter: invert(1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"><p><a href=".">Index</a></p></div>
|
||||
<div id="messages"></div>
|
||||
<div id="fixtures"></div>
|
||||
<script>
|
||||
var param = window.location.search.substr(1);
|
||||
if(param === "coverage"){
|
||||
Object.assign = null;
|
||||
Object.values = null;
|
||||
window["requestAnimationFrame"] = null;
|
||||
window["cancelAnimationFrame"] = null;
|
||||
window["Promise"] = null;
|
||||
window["_Proxy"] = window["Proxy"];
|
||||
window["Proxy"] = null;
|
||||
document.write('<script type="text/javascript" src="dist/dist/flexsearch.pre.js"><\/script>');
|
||||
}
|
||||
else if(param === "es5" || param === "light" || param === "min"){
|
||||
document.write('<script type="text/javascript" src="../dist/flexsearch.' + param + '.js"><\/script>');
|
||||
}
|
||||
else{
|
||||
document.write('<script type="text/javascript" src="dist/flexsearch.pre.js"><\/script>');
|
||||
}
|
||||
</script>
|
||||
<script>window["Proxy"] = window["_Proxy"];</script>
|
||||
<script src="node_modules/mocha/mocha.js"></script>
|
||||
<script src="node_modules/chai/chai.js"></script>
|
||||
<script>
|
||||
window.initMochaPhantomJS && initMochaPhantomJS();
|
||||
mocha.ui('bdd');
|
||||
mocha.reporter('html');
|
||||
mocha.setup('bdd');
|
||||
var expect = chai.expect;
|
||||
var env = "min";
|
||||
</script>
|
||||
<script src="test.js"></script>
|
||||
<!--<script src="test.es6.js"></script>-->
|
||||
<script>
|
||||
if(window.mochaPhantomJS) {
|
||||
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else{
|
||||
|
||||
mocha.run();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
56
test/server.js
Normal file
56
test/server.js
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var port = process.argv[2];
|
||||
|
||||
if(!port){
|
||||
|
||||
if(/^win/.test(process.platform)){
|
||||
|
||||
port = 80;
|
||||
}
|
||||
else{
|
||||
|
||||
port = 8080;
|
||||
}
|
||||
}
|
||||
|
||||
var ws = require('web-servo');
|
||||
|
||||
ws.config({
|
||||
|
||||
"server": {
|
||||
"port": port,
|
||||
"dir": "/",
|
||||
"exitOnError": false,
|
||||
"ssl": {
|
||||
"enabled": false,
|
||||
"key": "",
|
||||
"cert": ""
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"default": "index.html"
|
||||
},
|
||||
"methods": {
|
||||
"allowed": [
|
||||
"OPTIONS",
|
||||
"GET",
|
||||
"POST",
|
||||
"HEAD",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE"
|
||||
//"COPY",
|
||||
//"LINK",
|
||||
//"UNLINK",
|
||||
//"TRACE",
|
||||
//"CONNECT"
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
//ws.setConfigVar('server.port', port);
|
||||
ws.silent().start();
|
||||
|
||||
console.log("-----------------------------------------------------");
|
||||
console.log("Hit CTRL-C to stop the server...");
|
Reference in New Issue
Block a user