-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug 1449038 - Add a simple weighted search to KeywordService #317
Conversation
294b56b
to
5ae26ab
Compare
/assign @benjaminapetersen PTAL |
5ae26ab
to
0ab999b
Compare
0ab999b
to
43fa21b
Compare
reviewing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor things, mostly wondering if we want it to handle both w & w/o weights.
if (_.isEmpty(keywords)) { | ||
return []; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can we use _.reduce( )
or _.flatten(_.map())
vs manually creating [ ]
and _.each()
to .push()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give some example code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outermost:
var weightedSearch = function(objects, filterFields, keywords) {
if(_.isEmpty(keywords)) {
return [];
}
var results = _.reduce(objects, function(result, object) {
// do scoring work .....
if (score > 0) {
results.push({
object: object,
score: score
});
}
return result;
}, []);
// Sort first by score, then by display name for items that have the same score.
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']);
return _.map(orderedResult, 'object');
}
Could possibly do the score
and matchesKeyword
similarly, but def isn't a huge deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I'm not clear on the benefit.
Since _.reduce
can change result to anything, you have to read the code carefully to see that it's just appending values to an array. I feel like _.each
/ push
is easier to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I prob should not have suggested reduce
over like _.compact(_.map(objects))
, its too general purpose.
Its prob just the imperative vs declarative discussion... I'd rather not see the "noise" of manually making the new array(s) when we have a number of good functions that do that for us.
That said, is def a (subjective) nit, and not a huge issue 😄
@@ -107,4 +107,94 @@ describe('KeywordService', function() { | |||
expect(result).toEqual(mockData); | |||
}); | |||
}); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
big pts for tests! much easier to review & figure out what the new stuff is doing.
} | ||
}; | ||
|
||
it('should honor field weights', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is this the kind of configuration we might want to do once up front, via $provider
in app.js
.cofig()
, or would we want to custom config weights & paths for every use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ie, config
some functions & cache them, so we don't have copy / paste repeats of the setup in multiple places. I don't know how many times we will use this search feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will vary by the kind of resource and the context, so I think this has to be up to the caller.
}); | ||
|
||
it('should match all keywords', function() { | ||
var keywords = KeywordService.generateKeywords('maria db'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe unrelated, but wonder if .generateKeywords
should take either 'string of multiple'
or ['array','of','multiple']
.
var orderedResult = _.orderBy(results, ['score', displayName], ['desc', 'asc']); | ||
return _.map(orderedResult, 'object'); | ||
}; | ||
|
||
return { | ||
filterForKeywords: filterForKeywords, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have both a search
and a weightedSearch
? or could weightedSearch
be used w/o weights, just with keyword
and objects
(perhaps if paths was last & optional)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filterForKeywords is basically weightedSearch without the weights
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose naming symmetry. Prob not big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
I think all my questions answered, def looks good!
https://trello.com/c/2fFSJMX1
https://bugzilla.redhat.com/show_bug.cgi?id=1449038