[Search] Correct search updating

The search controller now updates the display
results list, then repeatedly asks the
aggregator to update until the timestamps
all are at least as new as the one that the
controller originally gave for the query.
Basically, the search now updates correctly
without having to press enter again.
This commit is contained in:
shale 2015-07-21 14:23:44 -07:00
parent 41c38f202d
commit 5a93e5a2bc
6 changed files with 77 additions and 38 deletions

View File

@ -15,7 +15,7 @@
{
"key": "SearchController",
"implementation": "controllers/SearchController.js",
"depends": [ "$scope", "searchService", "objectService" ]
"depends": [ "$scope", "$timeout", "searchService" ]
},
{
"key": "SearchbarController",

View File

@ -31,7 +31,7 @@
value=""
ng-keyup="controller.search('searchinput')"
style="width: 66%"/>
</div>
</div>
<!-- some spacing -->
<div style="height: 30px"></div>

View File

@ -41,7 +41,8 @@ define(
* aggregated
*/
function SearchAggregator(providers) {
var latestMergedResults = [];
var latestMergedResults = [],
lastMergeTimestamps = [];
// Remove extra objects that have the same ID
function filterRepeats(results) {
@ -104,11 +105,13 @@ define(
}
function updateResults() {
var newerResults = [];
var newerResults = [],
providerTimestamps = [];
// For each provider, get its most recent results
for (var i = 0; i < providers.length; i += 1) {
newerResults = newerResults.concat(providers[i].getLatest());
newerResults = newerResults.concat(providers[i].getLatestResults());
providerTimestamps.push(providers[i].getLatestTimestamp());
}
// Clean up
@ -117,27 +120,32 @@ define(
// After all that is done, now replace latestMergedResults with this
latestMergedResults = newerResults;
lastMergeTimestamps = providerTimestamps;
}
// Calls the searches of each of the providers, then
// merges the results lists so that there are not redundant
// results
/**
*
* Sends a query to each of the providers, then updates the globl
* latestMergedResults accordingly.
*
* @param inputID The name of the ID property of the html text
* input where this funcion should find the search term.
* @param timestamp (optional) The time at which this function
* was called. This timestamp will be associated with the
* latest results list, which allows us to see if it has been
* updated. If not provided, this aggregator will.
*/
function queryAll(inputID) {
var promises = [],
date = new Date(),
function queryAll(inputID, timestamp) {
// If there's not a timestamp, make this time the timestamp
if (!timestamp) {
var date = new Date();
timestamp = date.getTime();
}
// Send the query to all the providers
for (var i = 0; i < providers.length; i += 1) {
promises.push(
providers[i].query(
inputID, timestamp, DEFAULT_MAX_RESULTS, DEFUALT_TIMEOUT
)
);
providers[i].query(inputID, timestamp, DEFAULT_MAX_RESULTS, DEFUALT_TIMEOUT);
}
// TODO: Then we want to 'Get the latest results from all the providers'
// And then we might also want to check to see if the timestamp
// is correct.
@ -148,9 +156,17 @@ define(
return {
sendQuery: queryAll,
updateResults: updateResults,
getLatestResults: function (start, stop) {
// TODO: Make sure that slice handles out of bounds
return latestMergedResults.slice(start, stop);
// By default if there are no start or stop provided, will return
// the entire thing.
var a = latestMergedResults.slice(start, stop);
return a;
},
getLatestTimestamps: function () {
var b = lastMergeTimestamps;
return b;
}
};
}

View File

@ -28,19 +28,35 @@ define(function () {
"use strict";
function SearchController($scope, searchService, objectService) {
function SearchController($scope, $timeout, searchService) {
function search(inputID) {
var date = new Date(),
timestamp = date.getTime(),
numResults = 20;
// Later, the search result format will be different
// Will need to compile search result list (for this
// result page) here, using pseudo linkedlist searchResult
// Send the query
searchService.sendQuery(inputID, timestamp);
searchService.sendQuery(inputID);/*.then(function (c) {
//$scope.results = c;
});*/
$scope.results = searchService.getLatestResults(0, 5);
console.log('$scope results', $scope.results);
// Get the results
$scope.results = searchService.getLatestResults(0, numResults);
// Check to make sure that these results are the latest ones
function waitForLatest() {
var timestamps = searchService.getLatestTimestamps(),
areOld = timestamps.some(function(c) {return c < timestamp;});
// If any of the timestamps are older than the one we made the query with
if (areOld) {
// Then wait and try to update again
searchService.updateResults();
var latest = searchService.getLatestResults(0, numResults);
$timeout(waitForLatest, 100);
} else {
// We got the latest results now
$scope.results = searchService.getLatestResults(0, numResults);
}
}
waitForLatest();
}
return {

View File

@ -46,7 +46,7 @@ define(
function GenericSearchProvider($rootScope, $timeout, objectService, workerService) {
var worker = workerService.run('genericSearchWorker'),
latestResults = [],
lastSearchTimestamp;
lastSearchTimestamp = 0;
// Tell the web worker to add a new item's model to its list of items.
function indexItem(domainObject) {
@ -76,7 +76,6 @@ define(
worker.onmessage = handleResponse;
function handleResponse(event) {
console.log('handleResponse', event.data);
if (event.data.request === 'search') {
// Convert the ids given from the web worker into domain objects
var ids = [];
@ -93,7 +92,6 @@ define(
});
}
lastSearchTimestamp = event.data.timestamp;
console.log('updated latestResults', latestResults, 'with time', lastSearchTimestamp);
});
}
// If the message was from 'index', we don't need to do anything
@ -197,8 +195,12 @@ define(
return {
query: queryGeneric,
getLatest: function () {
getLatestResults: function () {
return latestResults;
},
getLatestTimestamp: function () {
return lastSearchTimestamp;
}
};
}

View File

@ -44,7 +44,6 @@
function index(data) {
// Takes an object model
// Add to indexedItems
console.log('webworker index', data);
// TODO: Since this is only within genericsearch, do
// we really need to check if the index already holds it?
@ -64,7 +63,18 @@
// Helper function for serach()
function convertToTerms(input) {
return input.split(' ');
var terms = input;
// Shave any spaces off of the ends of the input
while (terms.substr(0, 1) === ' ') {
terms = terms.substring(1, terms.length);
}
while (terms.substr(terms.length - 1, 1) === ' ') {
terms = terms.substring(0, terms.length - 1);
}
// Then split it at the spaces
terms = terms.split(' ');
console.log('terms', terms);
return terms;
}
// Helper function for search()
@ -103,8 +113,6 @@
// Takes a search input and the number of items to find
// Converts it into search terms
// Gets matches from indexedItems
console.log('webworker search', data);
console.log('webworker indexedItems', indexedItems);
// This results array will hold objects which are composed of
// the object's id, model, and score. (The score is wrt only this
@ -126,8 +134,6 @@
}
}
console.log('webworker results', results);
var message = {
request: 'search',
results: results,
@ -141,7 +147,6 @@
}
self.onmessage = function (event) {
console.log('webworker onmessage');
if (event.data.request === 'index') {
// TODO: Don't really need to post here.
self.postMessage(index(event.data));