Simple full-text search for ember-cli apps using lunr.js.
This is a ember-cli wrapper for lunr.js, a small full-text search library for use in the browser. It indexes JSON documents and provides a simple search interface for retrieving documents that best match text queries.
Installing the library is as easy as:
ember install ember-cli-lunr
Lunr 2.0 uses immutable index, so, you'll have to have an array of items to be searched beforehand. For usage with Lunr 1.0, see 0.0.5 of this add-on.
Given a model named post,
// app/pods/post/model.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
});
First, you'll have to create an index with the documents (keep in mind indexes are immutable) using the Lunr class,
import Lunr from 'ember-cli-lunr/lunr';
...
// Pass in models to create method, this indexes all properties on the model.
let posts = Lunr.create({ models: get(this, 'posts') });
// Or you could specify just the properties that you want to index via the properties key.
let posts = Lunr.create({ models: get(this, 'posts'), properties: ['title'] });
Now, you can search anywhere in your app using the search
method. This method is just a wrapper around lunr.js search method. For more advanced searching, checkout the lunr.js guides.
posts.search('lorem ipsum');
Putting this all together in a controller,
// app/pods/posts/controller.js
import Controller from '@ember/controller';
import { get, set } from '@ember/object';
import Lunr from 'ember-cli-lunr/lunr';
export default Controller.extend({
// assuming posts array was set on controller from
// setupController in route.
posts: null,
searchQuery: null,
init() {
this._super(...arguments);
let postsIndex = Lunr.create({ models: get(this, 'posts') });
set(this, 'postsIndex', postsIndex);
},
result: computed('searchQuery', function() {
var query = this.get('searchQuery'),
resultIds = get(this, 'postsIndex').search(query).mapBy('ref');
return items.filter(function(item) {
return resultIds.contains(item.get('id'));
});
});
});
Please leave a ⭐ to show some support. Thanks!