[Search] Changed generic's matching implementation

Changed how the generic search provider determines
search matches. It now splits the search input into
search terms by spliting at spaces, and then scores
the results by how many of the terms appear as
substrings in the result.
This commit is contained in:
shale 2015-07-17 13:49:09 -07:00
parent c75d94289b
commit 9f5f14826b
3 changed files with 50 additions and 34 deletions

View File

@ -41,14 +41,14 @@
{ {
"provides": "searchService", "provides": "searchService",
"type": "provider", "type": "provider",
"implementation": "providers/ElasticsearchSearchProvider.js", "implementation": "providers/GenericSearchProvider.js",
"depends": [ "$http", "objectService", "ELASTIC_ROOT" ] "depends": [ "objectService" ]
}, },
{ {
"provides": "searchService", "provides": "searchService",
"type": "provider", "type": "provider",
"implementation": "providers/GenericSearchProvider.js", "implementation": "providers/ElasticsearchSearchProvider.js",
"depends": [ "objectService" ] "depends": [ "$http", "objectService", "ELASTIC_ROOT" ]
}, },
{ {
"provides": "searchService", "provides": "searchService",

View File

@ -79,6 +79,12 @@ define(
} }
}); });
/*
for (var i = 0; i < results.length; i++) {
console.log('score', results[i].score, 'for', results[i].object.getModel().name);
}
*/
return results; return results;
} }

View File

@ -85,39 +85,51 @@ define(
}); });
} }
// Generate a score for an item based on its similarity to a search term // Process the search input. Makes an array of search terms
// Very rudimentary // by splitting up the input at spaces.
function score(item, term) { function process(input) {
var name = item.object.getModel().name, return input.split(' ');
//numWordsinName = name.split(' ').length,
//numWordsinTerm = term.split(' ').length,
weight = 1.5,
score = (term.length / name.length) * weight;
return score;
} }
// Determines if this item can be a valid result for this search term // Generate a score for an item based on its similarity to a search term.
function match(item, term) { // The score is equal to the number of terms that are a substring of the
var itemModel = item.object.getModel(), // object name.
itemName = itemModel.name.toLocaleLowerCase(), function score(item, terms, originalInput) {
itemType = itemModel.type.toLocaleLowerCase(); var name = item.object.getModel().name.toLocaleLowerCase(),
weight = 1.5,
score = 0;// = (term.length / name.length) * weight;
return itemName.includes(term) || itemType.includes(term); for (var i = 0; i < terms.length; i++) {
// Increase the score if the term is in the item name
if (name.includes(terms[i])) {
score++;
}
// Make the score really big if the item name and
// the original search input are the same
if (name === originalInput.toLocaleLowerCase()) {
score += 50;
}
}
return score / weight;
} }
// Filter through a list of searchResults based on a search term // Filter through a list of searchResults based on a search term
function filterResults(results, term, resultsLength, validType) { function filterResults(results, originalInput, resultsLength, validType) {
var searchResults = [], var terms,
searchResults = [],
itemModel; itemModel;
// Split the original search input into search terms
terms = process(originalInput);
for (var i = 0; i < resultsLength; i += 1) { for (var i = 0; i < resultsLength; i += 1) {
// Prevent errors from getModel not being defined // Prevent errors from getModel not being defined
if (results[i].object.getModel) { if (results[i].object.getModel) {
// Include any items that match the term and are of valid type results[i].score = score(results[i], terms, originalInput);
if (match(results[i], term) && validType(results[i].object.getModel())) { // Include any items that match the terms and are of valid type
// Score the result if (results[i].score > 0 && validType(results[i].object.getModel())) {
score(results[i], term);
// Add the result to the result list // Add the result to the result list
searchResults.push(results[i]); searchResults.push(results[i]);
} }
@ -146,8 +158,9 @@ define(
* @param maxResults (optional) the maximum number of results * @param maxResults (optional) the maximum number of results
* that this function should return * that this function should return
*/ */
function queryManual(inputID, validType, maxResults) { function queryGeneric(inputID, validType, maxResults) {
var term, var input,
terms = [],
searchResults = [], searchResults = [],
resultsLength; resultsLength;
@ -159,10 +172,7 @@ define(
} }
// Get the user input // Get the user input
term = document.getElementById(inputID).value; input = document.getElementById(inputID).value;
// Make not case sensitive
term = term.toLocaleLowerCase();
// Get items list // Get items list
return getItems().then(function (searchResultItems) { return getItems().then(function (searchResultItems) {
@ -174,7 +184,7 @@ define(
} }
// Then filter through the items list // Then filter through the items list
searchResults = filterResults(searchResultItems, term, resultsLength, validType); searchResults = filterResults(searchResultItems, input, resultsLength, validType);
//console.log('filtered searchResults (in Everything)', searchResults); //console.log('filtered searchResults (in Everything)', searchResults);
return searchResults; return searchResults;
@ -182,7 +192,7 @@ define(
} }
return { return {
query: queryManual query: queryGeneric
}; };
} }