Skip to content

Commit 5ae26ab

Browse files
committed
Bug 1449038 - Add a simple weighted search to KeywordService
https://trello.com/c/2fFSJMX1 https://bugzilla.redhat.com/show_bug.cgi?id=1449038
1 parent 0964cfa commit 5ae26ab

File tree

5 files changed

+278
-44
lines changed

5 files changed

+278
-44
lines changed

dist/origin-web-common-services.js

+47-1
Original file line numberDiff line numberDiff line change
@@ -2932,7 +2932,9 @@ angular.module('openshiftCommonServices')
29322932
;'use strict';
29332933

29342934
angular.module("openshiftCommonServices")
2935-
.service("KeywordService", function(){
2935+
.service("KeywordService", function($filter) {
2936+
2937+
var displayName = $filter('displayName');
29362938

29372939
var generateKeywords = function(filterText) {
29382940
if (!filterText) {
@@ -2977,8 +2979,52 @@ angular.module("openshiftCommonServices")
29772979
return filteredObjects;
29782980
};
29792981

2982+
// Perform a simple weighted search.
2983+
// weightedSearch is like filterForKeywords, except each field has a weight
2984+
// and the result is a sorted array of matches. filterFields is an array of
2985+
// objects with keys `path` and `weight`.
2986+
var weightedSearch = function(objects, filterFields, keywords) {
2987+
if (_.isEmpty(keywords)) {
2988+
return [];
2989+
}
2990+
2991+
var results = [];
2992+
_.each(objects, function(object) {
2993+
// Keep a score for matches, weighted by field.
2994+
var score = 0;
2995+
// Track whether we've matched all keywords.
2996+
var matchesKeyword = _.fill(Array(keywords.length), false);
2997+
_.each(filterFields, function(field) {
2998+
var value = _.get(object, field.path);
2999+
if (!value) {
3000+
return;
3001+
}
3002+
3003+
// For each matching keyword, add the field weight to the score.
3004+
_.each(keywords, function(regex, i) {
3005+
if (regex.test(value)) {
3006+
score += field.weight;
3007+
matchesKeyword[i] = true;
3008+
}
3009+
});
3010+
});
3011+
3012+
if (score > 0 && _.every(matchesKeyword)) {
3013+
results.push({
3014+
object: object,
3015+
score: score
3016+
});
3017+
}
3018+
});
3019+
3020+
// Sort first by score, then by display name for items that have the same score.
3021+
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']);
3022+
return _.map(orderedResult, 'object');
3023+
};
3024+
29803025
return {
29813026
filterForKeywords: filterForKeywords,
3027+
weightedSearch: weightedSearch,
29823028
generateKeywords: generateKeywords
29833029
};
29843030
});

dist/origin-web-common.js

+48-2
Original file line numberDiff line numberDiff line change
@@ -5000,7 +5000,9 @@ angular.module('openshiftCommonServices')
50005000
;'use strict';
50015001

50025002
angular.module("openshiftCommonServices")
5003-
.service("KeywordService", function(){
5003+
.service("KeywordService", ["$filter", function($filter) {
5004+
5005+
var displayName = $filter('displayName');
50045006

50055007
var generateKeywords = function(filterText) {
50065008
if (!filterText) {
@@ -5045,11 +5047,55 @@ angular.module("openshiftCommonServices")
50455047
return filteredObjects;
50465048
};
50475049

5050+
// Perform a simple weighted search.
5051+
// weightedSearch is like filterForKeywords, except each field has a weight
5052+
// and the result is a sorted array of matches. filterFields is an array of
5053+
// objects with keys `path` and `weight`.
5054+
var weightedSearch = function(objects, filterFields, keywords) {
5055+
if (_.isEmpty(keywords)) {
5056+
return [];
5057+
}
5058+
5059+
var results = [];
5060+
_.each(objects, function(object) {
5061+
// Keep a score for matches, weighted by field.
5062+
var score = 0;
5063+
// Track whether we've matched all keywords.
5064+
var matchesKeyword = _.fill(Array(keywords.length), false);
5065+
_.each(filterFields, function(field) {
5066+
var value = _.get(object, field.path);
5067+
if (!value) {
5068+
return;
5069+
}
5070+
5071+
// For each matching keyword, add the field weight to the score.
5072+
_.each(keywords, function(regex, i) {
5073+
if (regex.test(value)) {
5074+
score += field.weight;
5075+
matchesKeyword[i] = true;
5076+
}
5077+
});
5078+
});
5079+
5080+
if (score > 0 && _.every(matchesKeyword)) {
5081+
results.push({
5082+
object: object,
5083+
score: score
5084+
});
5085+
}
5086+
});
5087+
5088+
// Sort first by score, then by display name for items that have the same score.
5089+
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']);
5090+
return _.map(orderedResult, 'object');
5091+
};
5092+
50485093
return {
50495094
filterForKeywords: filterForKeywords,
5095+
weightedSearch: weightedSearch,
50505096
generateKeywords: generateKeywords
50515097
};
5052-
});
5098+
}]);
50535099
;'use strict';
50545100

50555101
angular.module('openshiftCommonServices')

0 commit comments

Comments
 (0)