mirror of
				https://github.com/Brandon-Rozek/website-theme.git
				synced 2025-11-04 11:31:12 +00:00 
			
		
		
		
	Merge pull request #17 from koirand/search
Imprement search engine by ngram Close #5
This commit is contained in:
		
						commit
						b4e0b7c0c9
					
				
					 4 changed files with 3556 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -22,6 +22,6 @@
 | 
			
		|||
  {{ partial "footer.html" . }}
 | 
			
		||||
  <script src="/js/jquery-3.3.1.min.js"></script>
 | 
			
		||||
  <script src="/js/jquery.mark.es6.min.js"></script>
 | 
			
		||||
  <script src="/js/fuse.min.js"></script>
 | 
			
		||||
  <script src="/js/lunr.js"></script>
 | 
			
		||||
  <script src="/js/search.js"></script>
 | 
			
		||||
{{ end }}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								static/js/fuse.min.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								static/js/fuse.min.js
									
										
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3471
									
								
								static/js/lunr.js
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										3471
									
								
								static/js/lunr.js
									
										
									
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,25 +1,87 @@
 | 
			
		|||
var fuse
 | 
			
		||||
var lunrIndex
 | 
			
		||||
var lunrResult
 | 
			
		||||
var pagesIndex
 | 
			
		||||
 | 
			
		||||
var bigramTokeniser = function (obj, metadata) {
 | 
			
		||||
  if (obj == null || obj == undefined) {
 | 
			
		||||
    return []
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (Array.isArray(obj)) {
 | 
			
		||||
    return obj.map(function (t) {
 | 
			
		||||
      return new lunr.Token(
 | 
			
		||||
        lunr.utils.asString(t).toLowerCase(),
 | 
			
		||||
        lunr.utils.clone(metadata)
 | 
			
		||||
      )
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var str = obj.toString().trim().toLowerCase(),
 | 
			
		||||
      tokens = []
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i <= str.length - 2; i++) {
 | 
			
		||||
    var tokenMetadata = lunr.utils.clone(metadata) || {}
 | 
			
		||||
    tokenMetadata["position"] = [i, i + 2]
 | 
			
		||||
    tokenMetadata["index"] = tokens.length
 | 
			
		||||
    tokens.push(
 | 
			
		||||
      new lunr.Token (
 | 
			
		||||
        str.slice(i, i + 2),
 | 
			
		||||
        tokenMetadata
 | 
			
		||||
      )
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return tokens
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var queryNgramSeparator = function (query) {
 | 
			
		||||
  var str = query.toString().trim().toLowerCase(),
 | 
			
		||||
      tokens = []
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i <= str.length - 2; i++) {
 | 
			
		||||
    tokens.push(str.slice(i, i + 2))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return tokens.join(' ')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Preparation for searching
 | 
			
		||||
 * Preparation for using lunr.js
 | 
			
		||||
 */
 | 
			
		||||
function initSearch () {
 | 
			
		||||
function initLunr () {
 | 
			
		||||
  $.getJSON('index.json').done(function (index) {
 | 
			
		||||
    var options = {
 | 
			
		||||
      shouldSort: true,
 | 
			
		||||
      tokenize: true,
 | 
			
		||||
      matchAllTokens: true,
 | 
			
		||||
      threshold: 0.3,
 | 
			
		||||
      minMatchCharLength: 5,
 | 
			
		||||
      keys: ['title', 'body']
 | 
			
		||||
    }
 | 
			
		||||
    fuse = new Fuse(index, options)
 | 
			
		||||
    pagesIndex = index
 | 
			
		||||
    lunrIndex = lunr(function () {
 | 
			
		||||
      this.tokenizer = bigramTokeniser
 | 
			
		||||
      this.pipeline.reset()
 | 
			
		||||
      this.ref('ref')
 | 
			
		||||
      this.field('title', { boost: 10 })
 | 
			
		||||
      this.field('body')
 | 
			
		||||
      this.metadataWhitelist = ['position']
 | 
			
		||||
      for (var page of pagesIndex) {
 | 
			
		||||
        this.add(page)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }).fail(function (jqxhr, textStatus, error) {
 | 
			
		||||
    var err = textStatus + ', ' + error
 | 
			
		||||
    console.error('Error getting Hugo index flie:', err)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Searching pages using lunr
 | 
			
		||||
 * @param {String} query Query string for searching
 | 
			
		||||
 * @return {Object[]} Array of search results
 | 
			
		||||
 */
 | 
			
		||||
function search (query) {
 | 
			
		||||
  lunrResult = lunrIndex.search(queryNgramSeparator(query))
 | 
			
		||||
  return lunrResult.map(function (result) {
 | 
			
		||||
    return pagesIndex.filter(function (page) {
 | 
			
		||||
      return page.ref === result.ref
 | 
			
		||||
    })[0]
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Setup UI for Search
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +95,7 @@ function initUI () {
 | 
			
		|||
  // Event when chenging query
 | 
			
		||||
  $('#searchBoxInput').keyup(function () {
 | 
			
		||||
    var $searchResults = $('#searchResults')
 | 
			
		||||
    var query = $(this).val().trim()
 | 
			
		||||
    var query = $(this).val()
 | 
			
		||||
 | 
			
		||||
    // Icon switching
 | 
			
		||||
    if (query.length) {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +113,7 @@ function initUI () {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Display search results
 | 
			
		||||
    renderResults(fuse.search(query))
 | 
			
		||||
    renderResults(search(query))
 | 
			
		||||
    $searchResults.show()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +128,7 @@ function initUI () {
 | 
			
		|||
function renderResults (results) {
 | 
			
		||||
  var $searchResults = $('#searchResults')
 | 
			
		||||
  var query = $('#searchBoxInput').val()
 | 
			
		||||
  var SUMMARY_INCLUDE = 50
 | 
			
		||||
  var BODY_LENGTH = 100
 | 
			
		||||
  var MAX_PAGES = 10
 | 
			
		||||
 | 
			
		||||
  // Clear search result
 | 
			
		||||
| 
						 | 
				
			
			@ -81,10 +143,13 @@ function renderResults (results) {
 | 
			
		|||
  // Only show the ten first results
 | 
			
		||||
  results.slice(0, MAX_PAGES).forEach(function (result, idx) {
 | 
			
		||||
    var $searchResultPage = $('<div class="searchResultPage">')
 | 
			
		||||
    var matchPosition = result.body.indexOf(query.split(' ')[0])
 | 
			
		||||
    var bodyStartPosition = matchPosition - SUMMARY_INCLUDE > 0 ? matchPosition - SUMMARY_INCLUDE : 0
 | 
			
		||||
    var metadata = lunrResult[idx].matchData.metadata
 | 
			
		||||
    var matchPosition = metadata[Object.keys(metadata)[0]].body ? metadata[Object.keys(metadata)[0]].body.position[0][0] : 0
 | 
			
		||||
    var bodyStartPosition = (matchPosition - (BODY_LENGTH / 2) > 0) ? matchPosition - (BODY_LENGTH / 2) : 0
 | 
			
		||||
 | 
			
		||||
    $searchResultPage.append('<a class="searchResultTitle" href="' + result.ref + '">' + result.title + '</a>')
 | 
			
		||||
    $searchResultPage.append('<div class="searchResultBody">' + result.body.substr(bodyStartPosition, SUMMARY_INCLUDE * 2) + '</div>')
 | 
			
		||||
 | 
			
		||||
    $searchResultPage.append('<div class="searchResultBody">' + result.body.substr(bodyStartPosition, BODY_LENGTH) + '</div>')
 | 
			
		||||
    $searchResults.append($searchResultPage)
 | 
			
		||||
 | 
			
		||||
    // Highlight keyword
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +157,7 @@ function renderResults (results) {
 | 
			
		|||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
initSearch()
 | 
			
		||||
initLunr()
 | 
			
		||||
 | 
			
		||||
$(function () {
 | 
			
		||||
  initUI()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue