Created
December 17, 2018 11:24
-
-
Save VanDalkvist/4e2b5aa651c54b53ed4cde15f2be0799 to your computer and use it in GitHub Desktop.
Angularjs Search service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
angular | |
.module('projectName') | |
.service('searchService', _searchService); | |
function _searchService($log, $q, _, lunr, reportsService, userService) { | |
var state; | |
var reindexPromise = $q.when(""); | |
var idFieldName = 'ms_id'; | |
// todo: for tests | |
window.search = state = { | |
index: null, | |
clustersHash: {} | |
}; | |
var service = this; | |
service.reindex = _.debounce(_reindex, 300); | |
service.ensureIndex = _ensureIndex; | |
service.search = _search; | |
// private functions | |
function _ensureIndex() { | |
if (state.index) return reindexPromise; | |
return _reindex(); | |
} | |
function _reindex() { | |
$log.debug('Search: Clusters indexing... '); | |
reindexPromise = reindexPromise.then(_fillIndex); | |
return reindexPromise; | |
} | |
function _initializeLunr() { | |
var instance = this; | |
// initialize lunr-languages ru plugin | |
instance.use(lunr.ru); | |
// setting a field to the list of fields that will be searchable within documents in the index. | |
instance.field('title', {boost: 10}); | |
// the property used to uniquely identify documents added to the index, | |
// by default this property is 'id' | |
instance.ref(idFieldName); | |
// removed stemmer | |
instance.pipeline.remove(lunr.ru.stemmer); | |
instance.pipeline.remove(lunr.ru.stopWordFilter); | |
instance.pipeline.add(trimmerEnRu); | |
} | |
function trimmerEnRu(token) { | |
var result = token | |
.replace(/^[^\wа-яёА-ЯЁ]+/, '') | |
.replace(/[^\wа-яёА-ЯЁ]+$/, ''); | |
return result === '' ? undefined : result; | |
}; | |
function _fillIndex() { | |
return userService.getProfile() | |
.then(function(profile) { | |
var promises = _(profile.topics).map('tag').map(_getClusters).value(); | |
return $q.all(promises); | |
}).then(function(results) { | |
return _.union.apply(null, results); | |
}).then(function(clusters) { | |
var newIndex = lunr(_initializeLunr); | |
state.clustersHash = _.indexBy(clusters, idFieldName); | |
_.each(clusters, _.partialRight(newIndex.add.bind(newIndex), true)); | |
state.index = newIndex; | |
$log.debug('Search: Clusters was indexed.'); | |
}); | |
} | |
function _getClusters(id) { | |
return reportsService.getReport(id).then(function(report) { | |
if (!report) return []; | |
_.each(report.clusters, function (cluster) { cluster.type = 'cluster'; cluster[idFieldName] = "c_" + cluster.id; }); | |
_.each(report.news, function (newsItem) { newsItem.type = 'news'; newsItem[idFieldName] = 'n_' + newsItem.id; }); | |
return report.clusters.concat(report.news); | |
}); | |
} | |
function _search(query) { | |
if (!query) return []; | |
var found = state.index.search(query); | |
return _(found).map('ref').map(_.propertyOf(state.clustersHash)).value(); | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment