From 9fb7a56e4c2b6873d7b6bd5d4bd48d7545900b44 Mon Sep 17 00:00:00 2001 From: bedroesb Date: Wed, 14 Jun 2023 10:31:21 +0200 Subject: [PATCH 1/2] start with flex search --- Gemfile.lock | 8 +-- _includes/head.html | 2 +- assets/js/flexsearch.js | 27 ++++++++++ assets/js/lunr.min.js | 6 --- assets/js/search-data.json | 42 +++++++-------- assets/js/search.js | 102 +++++++++++-------------------------- 6 files changed, 85 insertions(+), 102 deletions(-) create mode 100644 assets/js/flexsearch.js delete mode 100644 assets/js/lunr.min.js diff --git a/Gemfile.lock b/Gemfile.lock index e3b9915f..36a11114 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.0.4.3) + activesupport (7.0.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -24,7 +24,7 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.8.1) - faraday (2.7.4) + faraday (2.7.6) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) @@ -86,7 +86,7 @@ GEM activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.12.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) jekyll (3.9.3) addressable (~> 2.4) @@ -210,7 +210,7 @@ GEM jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.18.0) - nokogiri (1.14.3-x86_64-linux) + nokogiri (1.15.2-x86_64-linux) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) diff --git a/_includes/head.html b/_includes/head.html index 8de55503..4ae7fec6 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -49,7 +49,7 @@ {%- endif %} - + diff --git a/assets/js/flexsearch.js b/assets/js/flexsearch.js new file mode 100644 index 00000000..a8e519d9 --- /dev/null +++ b/assets/js/flexsearch.js @@ -0,0 +1,27 @@ +/**! + * FlexSearch.js v0.7.31 (Compact) + * Copyright 2018-2022 Nextapps GmbH + * Author: Thomas Wilkerling + * Licence: Apache-2.0 + * https://github.com/nextapps-de/flexsearch + */ +(function(self){'use strict';var t;function v(a){return"undefined"!==typeof a?a:!0}function w(a){const b=Array(a);for(let c=0;c=this.m&&(u||!n[l])){var f=P(q,e,r),g="";switch(this.C){case "full":if(2f;h--)if(h-f>=this.m){var k=P(q,e,r,d,f);g=l.substring(f,h);Q(this,n,g,k,a,c)}break}case "reverse":if(1=this.m&&Q(this,n, +g,P(q,e,r,d,h),a,c);g=""}case "forward":if(1=this.m&&Q(this,n,g,f,a,c);break}default:if(this.F&&(f=Math.min(f/this.F(b,l,r)|0,q-1)),Q(this,n,l,f,a,c),u&&1=this.m&&!d[l]){d[l]=1;const p=this.h&&l>f;Q(this,m,p?f:l,P(g+(e/2>g?0:1),e,r,h-1,k-1),a,c,p?l:f)}}}}this.D||(this.register[a]=1)}}return this}; +function P(a,b,c,e,d){return c&&1=this.m&&!c[q])if(this.s||f||this.map[q])k[u++]=q,c[q]=1;else return e;a=k;d=a.length}if(!d)return e;b||(b=100);h=this.depth&&1=e)))break;if(n){if(f)return ma(k,e,0);b[b.length]=k;return}}return!c&&k}function ma(a,b,c){a=1===a.length?a[0]:[].concat.apply([],a);return c||a.length>b?a.slice(c,c+b):a} +function na(a,b,c,e){c?(e=e&&b>c,a=(a=a[e?b:c])&&a[e?c:b]):a=a[b];return a}t.contain=function(a){return!!this.register[a]};t.update=function(a,b){return this.remove(a).add(a,b)};t.remove=function(a,b){const c=this.register[a];if(c){if(this.D)for(let e=0,d;eb||c)d=d.slice(c,c+b);e&&(d=qa.call(this,d));return{tag:a,result:d}}}function qa(a){const b=Array(a.length);for(let c=0,e;c=this.length)return D.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},D.QueryLexer.prototype.width=function(){return this.pos-this.start},D.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},D.QueryLexer.prototype.backup=function(){--this.pos},D.QueryLexer.prototype.acceptDigitRun=function(){for(var e,t;t=(e=this.next()).charCodeAt(0),47= 200 && request.status < 400) { var docs = JSON.parse(request.responseText); + var options = { - lunr.tokenizer.separator = /[\s/]+/ - - var index = lunr(function () { - this.ref('id'); - this.field('title', { boost: 200 }); - this.field('content', { boost: 2 }); - this.field('relUrl'); - this.metadataWhitelist = ['position'] - - for (var i in docs) { - this.add({ - id: i, - title: docs[i].title, - content: docs[i].content, - relUrl: docs[i].relUrl - }); - } - }); + keys: ["title", "content", "subtitle","url"] + }; + + var index = new FlexSearch.Index(options); + var document = new FlexSearch.Document(options); + var worker = new FlexSearch.Worker(options); - searchLoaded(index, docs); + index.add(docs, options); + searchLoaded(index); } else { console.log('Error loading ajax request. Request status:' + request.status); } @@ -71,8 +60,8 @@ permalink: assets/js/search.js request.send(); } - function searchLoaded(index, docs) { - var index = index; + function searchLoaded(fuse) { + var docs = docs; var searchInput = document.getElementById('search-input'); var searchResults = document.getElementById('search-results'); @@ -110,28 +99,7 @@ permalink: assets/js/search.js return; } - var results = index.query(function (query) { - var tokens = lunr.tokenizer(input) - query.term(tokens, { - boost: 10 - }); - query.term(tokens, { - wildcard: lunr.Query.wildcard.TRAILING - }); - }); - - if ((results.length == 0) && (input.length > 2)) { - var tokens = lunr.tokenizer(input).filter(function (token, i) { - return token.str.length < 20; - }) - if (tokens.length > 0) { - results = index.query(function (query) { - query.term(tokens, { - editDistance: Math.round(Math.sqrt(input.length / 2 - 1)) - }); - }); - } - } + var results = fuse.search(input); if (results.length == 0) { var noResultsDiv = document.createElement('div'); @@ -142,33 +110,25 @@ permalink: assets/js/search.js } else { var resultsList = document.createElement('ul'); searchResults.appendChild(resultsList); + console.log(results); + for (var result in results) { + console.log(result); + addResult(resultsList, result['item']); + searchIndex = currentSearchIndex + } - addResults(resultsList, results, 0, 10, 100, currentSearchIndex); - } - - function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) { if (searchIndex != currentSearchIndex) { return; } - for (var i = start; i < (start + batchSize); i++) { - if (i == results.length) { - return; - } - addResult(resultsList, results[i]); - } - setTimeout(function () { - addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex); - }, batchMillis); } function addResult(resultsList, result) { - var doc = docs[result.ref]; - + var resultsListItem = document.createElement('li'); resultsList.appendChild(resultsListItem); var resultLink = document.createElement('a'); - resultLink.setAttribute('href', doc.url); + resultLink.setAttribute('href', result.url); resultsListItem.appendChild(resultLink); var resultTitle = document.createElement('div'); @@ -181,15 +141,15 @@ permalink: assets/js/search.js var resultDocTitle = document.createElement('div'); resultDocTitle.classList.add('search-result-doc-title'); - resultDocTitle.innerHTML = doc.doc; + resultDocTitle.innerHTML = result.title; resultDoc.appendChild(resultDocTitle); var resultDocOrSection = resultDocTitle; - if (doc.doc != doc.title) { + if (result.title != result.subtitle) { resultDoc.classList.add('search-result-doc-parent'); var resultSection = document.createElement('div'); resultSection.classList.add('search-result-section'); - resultSection.innerHTML = doc.title; + resultSection.innerHTML = result.subtitle; resultTitle.appendChild(resultSection); resultDocOrSection = resultSection; } @@ -199,8 +159,8 @@ permalink: assets/js/search.js var contentPositions = []; for (var j in metadata) { var meta = metadata[j]; - if (meta.title) { - var positions = meta.title.position; + if (meta.subtitle) { + var positions = meta.subtitle.position; for (var k in positions) { titlePositions.push(positions[k]); } @@ -214,8 +174,8 @@ permalink: assets/js/search.js var ellipsesBefore = true; var ellipsesAfter = true; for (var k = 0; k < 4; k++) { - var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2); - var nextDot = doc.content.lastIndexOf('. ', previewStart - 2); + var nextSpace = result.content.lastIndexOf(' ', previewStart - 2); + var nextDot = result.content.lastIndexOf('. ', previewStart - 2); if ((nextDot >= 0) && (nextDot > nextSpace)) { previewStart = nextDot + 1; ellipsesBefore = false; @@ -229,8 +189,8 @@ permalink: assets/js/search.js previewStart = nextSpace + 1; } for (var k = 0; k < 4; k++) { - var nextSpace = doc.content.indexOf(' ', previewEnd + 1); - var nextDot = doc.content.indexOf('. ', previewEnd + 1); + var nextSpace = result.content.indexOf(' ', previewEnd + 1); + var nextDot = result.content.indexOf('. ', previewEnd + 1); if ((nextDot >= 0) && (nextDot < nextSpace)) { previewEnd = nextDot; ellipsesAfter = false; @@ -255,7 +215,7 @@ permalink: assets/js/search.js if (titlePositions.length > 0) { titlePositions.sort(function (p1, p2) { return p1[0] - p2[0] }); resultDocOrSection.innerHTML = ''; - addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions); + addHighlightedText(resultDocOrSection, result.subtitle, 0, result.subtitle.length, titlePositions); } if (contentPositions.length > 0) { @@ -287,7 +247,7 @@ permalink: assets/js/search.js resultPreviews.classList.add('search-result-previews'); resultLink.appendChild(resultPreviews); - var content = doc.content; + var content = result.content; for (var j = 0; j < Math.min(previewPositions.length, 3); j++) { var position = previewPositions[j]; From e95666f9a6a455cbec5f5eab9e3444b25045c65d Mon Sep 17 00:00:00 2001 From: bedroesb Date: Wed, 12 Jul 2023 15:16:30 +0200 Subject: [PATCH 2/2] further polishing --- assets/js/search.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/assets/js/search.js b/assets/js/search.js index 34a41119..71bdb7c8 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -38,16 +38,15 @@ permalink: assets/js/search.js if (request.status >= 200 && request.status < 400) { var docs = JSON.parse(request.responseText); var options = { - + tokenize: "forward", + suggest: true, keys: ["title", "content", "subtitle","url"] }; var index = new FlexSearch.Index(options); - var document = new FlexSearch.Document(options); - var worker = new FlexSearch.Worker(options); index.add(docs, options); - searchLoaded(index); + searchLoaded(document); } else { console.log('Error loading ajax request. Request status:' + request.status); } @@ -60,9 +59,8 @@ permalink: assets/js/search.js request.send(); } - function searchLoaded(fuse) { + function searchLoaded(index) { - var docs = docs; var searchInput = document.getElementById('search-input'); var searchResults = document.getElementById('search-results'); var currentInput; @@ -99,7 +97,7 @@ permalink: assets/js/search.js return; } - var results = fuse.search(input); + var results = index.search(input); if (results.length == 0) { var noResultsDiv = document.createElement('div');