[Search] Aggregator returns result object

The aggregator now returns a result object similar
to that of the providers, but the hits array contains
domain objects rather than searchResult objects.
Also removed overly complicated filterRepeats
function from the aggregator and replaced it with a
simpler one.
This commit is contained in:
slhale
2015-07-30 14:56:17 -07:00
parent 51bc7c6a7f
commit 15b7e3ac9b
2 changed files with 33 additions and 52 deletions

View File

@@ -44,58 +44,33 @@ define(
function SearchAggregator($q, providers) { function SearchAggregator($q, providers) {
var loading; var loading;
// Remove duplicate objects that have the same ID // Remove duplicate objects that have the same ID. Modifies the passed
function filterRepeats(results) { // array, and returns the number that were removed.
function filterDuplicates(results, total) {
var ids = [], var ids = [],
idToIndicies = {}, // 'dictionary' mapping IDs to a list of indicies numRemoved = 0;
filteredResults = [],
i,
id,
indicies,
highestScoringObject,
j;
// Create a list of indicies of objects that correspond to any object ID for (var i = 0; i < results.length; i += 1) {
for (i = 0; i < results.length; i += 1) { if (ids.indexOf(results[i].id) !== -1) {
id = results[i].id; // If this result's ID is already there, remove the object
results.splice(i, 1);
if (idToIndicies[id]) { numRemoved += 1;
// If the ID already exists in the dictionary, push this index to
// the end of the array it points to // Reduce loop index because we shortened the array
idToIndicies[id].push(i); i -= 1;
} else { } else {
// Else make a new entry in the dictionary with this ID, pointing // Otherwise add the ID to the list of the ones we have seen
// to this index ids.push(results[i].id);
idToIndicies[id] = [i];
// And also add this ID to the list of IDs that we have seen
ids.push(id);
} }
} }
// Now for each ID in the dictionary, we want to use the version of return numRemoved;
// the object that has a higher score
for (i = 0; i < ids.length; i += 1) {
id = ids[i];
indicies = idToIndicies[id];
highestScoringObject = results[indicies[0]];
for (j = 0; j < indicies.length; j += 1) {
// If the score of the object corresponding to this index of the results
// list has a higher score than the one we have, choose it instead
if (results[indicies[j]].score > highestScoringObject.score) {
highestScoringObject = results[indicies[j]];
}
}
filteredResults.push(highestScoringObject);
}
return filteredResults;
} }
// Order the objects from highest to lowest score in the array // Order the objects from highest to lowest score in the array.
// Modifies the passed array, as well as returns the modified array.
function orderByScore(results) { function orderByScore(results) {
results.sort(function (a, b) {
results = results.sort(function (a, b) {
if (a.score > b.score) { if (a.score > b.score) {
return -1; return -1;
} else if (b.score > a.score) { } else if (b.score > a.score) {
@@ -104,7 +79,6 @@ define(
return 0; return 0;
} }
}); });
return results; return results;
} }
@@ -127,26 +101,33 @@ define(
// Get promises for results arrays // Get promises for results arrays
return $q.all(resultPromises).then(function (resultObjects) { return $q.all(resultPromises).then(function (resultObjects) {
var results = [], var results = [],
totalSum = 0,
i; i;
// Merge results // Merge results
for (i = 0; i < resultObjects.length; i += 1) { for (i = 0; i < resultObjects.length; i += 1) {
results = results.concat(resultObjects[i].hits); results = results.concat(resultObjects[i].hits);
totalSum += resultObjects[i].total;
} }
results = filterRepeats(results); // Order by score first, so that when removing repeats we keep the higher scored ones
results = orderByScore(results); orderByScore(results);
totalSum = filterDuplicates(results, totalSum);
// We are done loading // We are done loading
loading = false; loading = false;
return results; return {
hits: results,
total: totalSum
};
}); });
} }
return { return {
/** /**
* Sends a query to each of the providers. Returns a promise * Sends a query to each of the providers. Returns a promise for
* for an array of domain object results. * a result object that has the format
* {hits: domainObject[], total: number}
* *
* @param inputText The text input that is the query. * @param inputText The text input that is the query.
*/ */

View File

@@ -58,10 +58,10 @@ define(function () {
// Send the query // Send the query
//searchService.sendQuery(inputText, setControllerResults); //searchService.sendQuery(inputText, setControllerResults);
searchService.query(inputText).then(function (results) { searchService.query(inputText).then(function (result) {
//console.log('controller - results', results); //console.log('controller - results', results);
fullResults = results; fullResults = result.hits;
$scope.results = results.slice(0, numResults); $scope.results = result.hits.slice(0, numResults);
}); });
} }