(function () { 'use strict'; var serviceId = 'search'; angular.module('app').factory(serviceId, [ search]); //service to wrap lunr.js for angular usage - currently handles searching items function search() { var index = lunr(function() { this.field('title'); this.field('details'); this.field('itemType'); this.field('displayType'); this.field('tags'); this.ref('itemId'); }); var service = { indexItems: indexItems, searchItem: searchItem }; //There is an issue in lunr.js where if your query string is a certain length you don't get results where you should //e.g. if you have a document containing 'styling' then searching for 'styl' will yield a result, //but then searching 'styli' or 'stylin' yield nothing //This is to do with the stemmer(?) in the code, so the workaround is to remove the stemmer //*reference: https://github.com/olivernn/lunr.js/issues/38 index.pipeline.remove(index.stemmer); return service; //index all items function indexItems(items) { items.forEach(function (item) { var mappedItem = itemMapper(item); index.add(mappedItem); }); return ; } //tells lunr what item properties to index function itemMapper(item) { if (item.itemType === 'Folder') { return { "itemId": item.itemId, "summary": item.summary, "details": item.details, "title": item.title, "itemType": item.itemType, "displayType": item.displayType, "tags": item.itemType } } else return { "itemId": item.itemId, "summary": item.summary, "details": item.details, "title": item.title, "itemType": item.itemType, "displayType": item.displayType, "tags": item.tags ? $.map(item.tags, function (tag) { return tag.text; }).join(' ') : [] } } //search items using the text attribute function searchItem(text) { if(text) return index.search(text); return null; } } })();