diff options
author | Dillon <dillonzq@outlook.com> | 2020-04-28 21:34:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-28 21:34:28 +0300 |
commit | 16a4e94117f118a358d1c0184db48e70a0aa63a9 (patch) | |
tree | a99069c4308bf229b87745c1dfe91661998b8b82 /src | |
parent | aa5f490aae97097c4b5984ef4e753d160d89d103 (diff) |
feat(search): add more params for search and improve search index (#279)
Diffstat (limited to 'src')
-rw-r--r-- | src/js/theme.js | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/src/js/theme.js b/src/js/theme.js index ebb9cf1b..66f1ad6e 100644 --- a/src/js/theme.js +++ b/src/js/theme.js @@ -93,6 +93,8 @@ class Theme { initSearch() { const searchConfig = this.config.search; + if (!searchConfig.maxResultLength) searchConfig.maxResultLength = 10; + if (!searchConfig.highlightTag) searchConfig.highlightTag = 'em'; const isMobile = this.util.isMobile(); if (!searchConfig || isMobile && this._searchMobileOnce || !isMobile && this._searchDesktopOnce) return; const classSuffix = isMobile ? 'mobile' : 'desktop'; @@ -173,15 +175,14 @@ class Theme { if (searchConfig.type === 'lunr') { const search = () => { if (lunr.queryHandler) query = lunr.queryHandler(query); - return this._index.search(query).slice(0, 12).map(({ ref, matchData: { metadata } }) => { + const results = {}; + this._index.search(query).forEach(({ ref, matchData: { metadata } }) => { const matchData = this._indexData[ref]; - let { title, content: context } = matchData; + let { uri, title, content: context } = matchData; + if (results[uri]) return; let position = 0; - Object.values(metadata).forEach(({ description, content }) => { - if (description) { - context = matchData.description; - position = -1; - } else if (content) { + Object.values(metadata).forEach(({ content }) => { + if (content) { const matchPosition = content.position[0][0]; if (matchPosition < position || position === 0) position = matchPosition; } @@ -194,16 +195,17 @@ class Theme { context = context.substr(0, CONTEXT_LENGTH); } Object.keys(metadata).forEach(key => { - title = title.replace(new RegExp(`(${key})`, 'gi'), '<em>$1</em>'); - context = context.replace(new RegExp(`(${key})`, 'gi'), '<em>$1</em>'); + title = title.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`); + context = context.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`); }); - return { - 'uri': matchData.uri, + results[uri] = { + 'uri': uri, 'title' : title, 'date' : matchData.date, 'context' : context, }; }); + return Object.values(results).slice(0, searchConfig.maxResultLength); } if (!this._index) { fetch(searchConfig.lunrIndexURL) @@ -212,14 +214,14 @@ class Theme { const indexData = {}; this._index = lunr(function () { if (searchConfig.lunrLanguageCode) this.use(lunr[searchConfig.lunrLanguageCode]); - this.ref('uri'); + this.ref('objectID'); this.field('title', { boost: 50 }); this.field('tags', { boost: 20 }); - this.field('description', { boost: 10 }); - this.field('content', { boost: 5 }); + this.field('categories', { boost: 20 }); + this.field('content', { boost: 10 }); this.metadataWhitelist = ['position']; data.forEach((record) => { - indexData[record.uri] = record; + indexData[record.objectID] = record; this.add(record); }); }); @@ -231,18 +233,28 @@ class Theme { }); } else finish(search()); } else if (searchConfig.type === 'algolia') { - $searchLoading.style.display = 'inline'; - $searchClear.style.display = 'none'; this._algoliaIndex = this._algoliaIndex || algoliasearch(searchConfig.algoliaAppID, searchConfig.algoliaSearchKey).initIndex(searchConfig.algoliaIndex); this._algoliaIndex - .search(query, { offset: 0, length: 12, attributesToHighlight: ['title', 'content'] }) + .search(query, { + offset: 0, + length: searchConfig.maxResultLength * 3, + attributesToHighlight: ['title'], + attributesToSnippet: ['content:30'], + highlightPreTag: `<${searchConfig.highlightTag}>`, + highlightPostTag: `</${searchConfig.highlightTag}>`, + }) .then(({ hits }) => { - finish(hits.map(({ uri, date, _highlightResult: { title, content } }) => ({ - uri: uri, - title: title.value, - date: date, - context: content.value, - }))); + const results = {}; + hits.forEach(({ uri, date, _highlightResult: { title }, _snippetResult: { content } }) => { + if (results[uri]) return; + results[uri] = { + uri: uri, + title: title.value, + date: date, + context: content.value, + }; + }); + finish(Object.values(results)); }) .catch(err => { console.error(err); |