Full-text search example using lunr.js
I did a little experiment today. I added full-text search to this website using lunr.js. Lunr is a simple full-text search engine that can run inside of a web browser using Javascript.
Lunr is a bit like solr, but much smaller and not as bright, as the author Oliver beautifully puts it.
With it I was able to add full text search to this site in less than an hour. That's pretty cool if you ask me. :)
You can try out the search function I built on the articles page of this website.
I also enabled source maps so you can see how I hacked together the search interface. But let me give you a rough overview.
Indexing
The indexing is performed when I build the static site. It's pretty simple.
// create the index
var index = lunr(function(){
// boost increases the importance of words found in this field
this.field('title', {boost: 10});
this.field('abstract', {boost: 2});
this.field('content');
// the id
this.ref('href');
});
// this is a store with some document meta data to display
// in the search results.
var store = {};
entries.forEach(function(entry){
index.add({
href: entry.href,
title: entry.title,
abstract: entry.abstract,
// hacky way to strip html, you should do better than that ;)
content: cheerio.load(entry.content.replace(/<[^>]*>/g, ' ')).root().text()
});
store[entry.href] = {title: entry.title, abstract: entry.abstract};
});
fs.writeFileSync('public/searchIndex.json', JSON.stringify({
index: index.toJSON(),
store: store
}));[^>
The resulting index is 1.3 MB, gzipping brings it down to a more reasonable 198 KB.
Search Interface
The other part of the equation is the search interface. I went for some simple jQuery hackery.
jQuery(function($) {
var index,
store,
data = $.getJSON(searchIndexUrl);
data.then(function(data){
store = data.store,
// create index
index = lunr.Index.load(data.index)
});
$('.search-field').keyup(function() {
var query = $(this).val();
if(query === ''){
jQuery('.search-results').empty();
}
else {
// perform search
var results = index.search(query);
data.then(function(data) {
$('.search-results').empty().append(
results.length ?
results.map(function(result){
var el = $('<p>')
.append($('<a>')
.attr('href', result.ref)
.text(store[result.ref].title)
);
if(store[result.ref].abstract){
el.after($('<p>').text(store[result.ref].abstract));
}
return el;
}) : $('<p><strong>No results found</strong></p>')
);
});
}
});
});
Learn More
If you want to learn more about how lunr works I recommend you to read this article by the author.
If you still want to learn more about search, then I can recommend this great free book on the subject called Introduction to Information Retrieval by Christopher D. Manning, Prabhakar Raghavan and Hinrich Schütze.