On Browser Search using Wink
May 23, 2019 by PrateekWink packages with a small footprint and high performance makes them a perfect candidate to use directly in the browser. In this post we’ll try to build a search functionality for our static site. You can view the demo here and check out the code on Github.
We’ll be using the bm25-text-search package for the search functionality and that will be our only dependency:
npm install wink-bm25-text-search --save
Next, we’ll setup Browserify and Grunt to bundle our JavaScript into a single file. This will also allow us to require
modules as we normally would in Node JS.
npm install browserify --save-dev
npm install grunt --save-dev
npm install grunt-browserify --save-dev
npm install grunt-contrib-watch --save-dev
Browserify can be run independently without Grunt, but we’ll use Grunt to watch for any changes and run Browserify automatically. This is what our Gruntfile.js
is going to look like:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
'bundle.js': 'search.js'
},
watch: {
files: ['search.js'],
tasks: ['browserify']
}
});
grunt.registerTask('default', ['watch']);
};
Before starting development we'll always run grunt
. This will take search.js
, look at all its dependencies, and put them all together to give us bundle.js
. This is the only file we'll need to include in our HTML.
For search.js
let's start by require
-ing the modules we need:
var bm25 = require( 'wink-bm25-text-search' );
var nlp = require( 'wink-nlp-utils' );
var docs = require( 'wink-bm25-text-search/sample-data/demo-data-for-wink-bm25.json' );
var getSpottedTerms = require('wink-bm25-text-search/runkit/get-spotted-terms.js');
Next, we’ll use the basic configuration as documented in the README and load the documents to be searched into it. You can take a look at the JSON we’re loading here.
var engine = bm25();
var pipe = [
nlp.string.lowerCase,
nlp.string.tokenize0,
nlp.tokens.removeWords,
nlp.tokens.stem,
nlp.tokens.propagateNegations
];
engine.defineConfig( { fldWeights: { title: 1, body: 2 } } );
engine.definePrepTasks( pipe );
docs.forEach( function ( doc, i ) {
engine.addDoc( doc, i );
} );
engine.consolidate();
And that’s it! We are now ready to use the engine
anywhere in our code to run the search. In our demo’s case we are getting an input from the user to search:
var results = engine.search(el.target.value);
You can see the rest of the glue code in search.js
that just displays the UI and the results on the page.
With Wink running in the browser there are endless possibilities for tools that can run with no latency. I am excited to see what you'll build with.