Skip to content

Commit 43fa21b

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 43fa21b

File tree

5 files changed

+307
-44
lines changed

5 files changed

+307
-44
lines changed

dist/origin-web-common-services.js

+52-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,57 @@ 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+
_.each(keywords, function(regex) {
2996+
var matchesKeyword = false;
2997+
_.each(filterFields, function(field) {
2998+
var value = _.get(object, field.path);
2999+
if (!value) {
3000+
return;
3001+
}
3002+
3003+
if (regex.test(value)) {
3004+
// For each matching keyword, add the field weight to the score.
3005+
score += field.weight;
3006+
matchesKeyword = true;
3007+
}
3008+
});
3009+
3010+
if (!matchesKeyword) {
3011+
// We've missed a keyword. Set score to 0 and short circuit the loop.
3012+
score = 0;
3013+
return false;
3014+
}
3015+
});
3016+
3017+
if (score > 0) {
3018+
results.push({
3019+
object: object,
3020+
score: score
3021+
});
3022+
}
3023+
});
3024+
3025+
// Sort first by score, then by display name for items that have the same score.
3026+
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']);
3027+
return _.map(orderedResult, 'object');
3028+
};
3029+
29803030
return {
29813031
filterForKeywords: filterForKeywords,
3032+
weightedSearch: weightedSearch,
29823033
generateKeywords: generateKeywords
29833034
};
29843035
});

dist/origin-web-common.js

+53-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,60 @@ 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+
_.each(keywords, function(regex) {
5064+
var matchesKeyword = false;
5065+
_.each(filterFields, function(field) {
5066+
var value = _.get(object, field.path);
5067+
if (!value) {
5068+
return;
5069+
}
5070+
5071+
if (regex.test(value)) {
5072+
// For each matching keyword, add the field weight to the score.
5073+
score += field.weight;
5074+
matchesKeyword = true;
5075+
}
5076+
});
5077+
5078+
if (!matchesKeyword) {
5079+
// We've missed a keyword. Set score to 0 and short circuit the loop.
5080+
score = 0;
5081+
return false;
5082+
}
5083+
});
5084+
5085+
if (score > 0) {
5086+
results.push({
5087+
object: object,
5088+
score: score
5089+
});
5090+
}
5091+
});
5092+
5093+
// Sort first by score, then by display name for items that have the same score.
5094+
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']);
5095+
return _.map(orderedResult, 'object');
5096+
};
5097+
50485098
return {
50495099
filterForKeywords: filterForKeywords,
5100+
weightedSearch: weightedSearch,
50505101
generateKeywords: generateKeywords
50515102
};
5052-
});
5103+
}]);
50535104
;'use strict';
50545105

50555106
angular.module('openshiftCommonServices')

0 commit comments

Comments
 (0)