mirror of
https://github.com/nasa/openmct.git
synced 2025-01-02 11:26:42 +00:00
[Search] Updated search service interface
The search service's interface now just consists of the two functions query() and isLoading(). query() returns a promise for an array or results, which eliminates the need for timeout polling like was previously done. The search providers have also been changed to reutrn promises.
This commit is contained in:
parent
5ee8dd239b
commit
1619f236cf
platform/features/search
@ -32,7 +32,7 @@
|
||||
"provides": "searchService",
|
||||
"type": "provider",
|
||||
"implementation": "providers/GenericSearchProvider.js",
|
||||
"depends": [ "objectService", "workerService", "roots[]" ]
|
||||
"depends": [ "$q", "objectService", "workerService", "roots[]" ]
|
||||
},
|
||||
{
|
||||
"provides": "searchService",
|
||||
@ -44,7 +44,7 @@
|
||||
"provides": "searchService",
|
||||
"type": "aggregator",
|
||||
"implementation": "SearchAggregator.js",
|
||||
"depends": [ "$timeout" ]
|
||||
"depends": [ "$q" ]
|
||||
}
|
||||
],
|
||||
"workers": [
|
||||
|
@ -37,17 +37,27 @@ define(
|
||||
* to be treated as one.
|
||||
*
|
||||
* @constructor
|
||||
* @param $q
|
||||
* @param $timeout Angular's $timeout service, a replacement for
|
||||
* JavaScript's setTimeout function.
|
||||
* @param {SearchProvider[]} providers the search providers to be
|
||||
* aggregated
|
||||
*/
|
||||
function SearchAggregator($timeout, providers) {
|
||||
var latestMergedResults = [],
|
||||
lastMergeTimestamps = [],
|
||||
lastQueryTimestamp = 0,
|
||||
function SearchAggregator($q,/* $timeout, */providers) {
|
||||
var //latestMergedResults = [],
|
||||
//lastMergeTimestamps = [],
|
||||
//lastQueryTimestamp = 0,
|
||||
loading;
|
||||
|
||||
function concatArrays(arrays) {
|
||||
var i,
|
||||
array = [];
|
||||
for (i = 0; i < arrays.length; i += 1) {
|
||||
array = array.concat(arrays[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Remove duplicate objects that have the same ID
|
||||
function filterRepeats(results) {
|
||||
var ids = [],
|
||||
@ -112,6 +122,7 @@ define(
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
// For documentation, see updateResults below.
|
||||
function updateResults() {
|
||||
var newerResults = [],
|
||||
@ -132,7 +143,9 @@ define(
|
||||
latestMergedResults = newerResults;
|
||||
lastMergeTimestamps = providerTimestamps;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// For documentation, see refresh below.
|
||||
function refresh(callback) {
|
||||
// We are loading results
|
||||
@ -158,20 +171,25 @@ define(
|
||||
}
|
||||
waitForLatest();
|
||||
}
|
||||
*/
|
||||
|
||||
// For documentation, see sendQuery below.
|
||||
function queryAll(inputText, callback, timestamp) {
|
||||
var date,
|
||||
i;
|
||||
var i,
|
||||
resultPromises = [];
|
||||
|
||||
// We are loading
|
||||
loading = true;
|
||||
|
||||
// If there's not a timestamp, make this time the timestamp
|
||||
if (!timestamp) {
|
||||
date = new Date();
|
||||
timestamp = date.getTime();
|
||||
timestamp = Date.now();
|
||||
}
|
||||
|
||||
// Update globals
|
||||
lastQueryTimestamp = timestamp;
|
||||
//lastQueryTimestamp = timestamp;
|
||||
|
||||
/*
|
||||
|
||||
// Send the query to all the providers
|
||||
for (i = 0; i < providers.length; i += 1) {
|
||||
@ -183,6 +201,31 @@ define(
|
||||
|
||||
// Start refresh loop
|
||||
refresh(callback);
|
||||
*/
|
||||
|
||||
// Instead, get back a bunch of promises from the providers
|
||||
|
||||
// Send the query to all the providers
|
||||
for (i = 0; i < providers.length; i += 1) {
|
||||
resultPromises.push(providers[i].query(inputText, timestamp, DEFAULT_MAX_RESULTS, DEFUALT_TIMEOUT));
|
||||
}
|
||||
//console.log('aggregator - result promises array', resultPromises);
|
||||
|
||||
return $q.all(resultPromises).then(function (resultsArrays) {
|
||||
var results = concatArrays(resultsArrays);
|
||||
results = filterRepeats(results);
|
||||
results = orderByScore(results);
|
||||
|
||||
// TODO: sync this with stuff,, timestamps
|
||||
//latestMergedResults = results;
|
||||
|
||||
//console.log('aggregator - final results', results);
|
||||
|
||||
// We are done loading
|
||||
loading = false;
|
||||
|
||||
return results;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
@ -198,7 +241,7 @@ define(
|
||||
* latest results list, which allows us to see if it has been
|
||||
* updated. If not provided, this aggregator will.
|
||||
*/
|
||||
sendQuery: queryAll,
|
||||
query: queryAll,
|
||||
|
||||
/**
|
||||
* Repeatedly updates the latest results until those results are
|
||||
@ -207,7 +250,9 @@ define(
|
||||
* @param callback A callback funtion which is a setter for the
|
||||
* results list, originally passed by the user of this service.
|
||||
*/
|
||||
/*
|
||||
refresh: refresh,
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the latest search results that have been calculated. The
|
||||
@ -219,17 +264,21 @@ define(
|
||||
* @param stop (optional) The index of latestMergedResults at
|
||||
* which to stop getting results.
|
||||
*/
|
||||
/*
|
||||
getLatestResults: function (start, stop) {
|
||||
return latestMergedResults.slice(start, stop);
|
||||
},
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the number of search results that have been calculated most
|
||||
* recently.
|
||||
*/
|
||||
/*
|
||||
getNumResults: function () {
|
||||
return latestMergedResults.length;
|
||||
},
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks to see if we are still waiting for the results to be
|
||||
|
@ -32,13 +32,16 @@ define(function () {
|
||||
|
||||
function SearchController($scope, searchService) {
|
||||
// Starting amount of results to load. Will get increased.
|
||||
var numResults = INITIAL_LOAD_NUMBER;
|
||||
var numResults = INITIAL_LOAD_NUMBER,
|
||||
fullResults = [];
|
||||
|
||||
/*
|
||||
// Function to be passed to the search service which allows it to set the
|
||||
// search template's results list
|
||||
function setControllerResults(results) {
|
||||
$scope.results = results.slice(0, numResults);
|
||||
}
|
||||
*/
|
||||
|
||||
function search() {
|
||||
var inputText = $scope.ngModel.input;
|
||||
@ -54,7 +57,12 @@ define(function () {
|
||||
numResults = INITIAL_LOAD_NUMBER;
|
||||
|
||||
// Send the query
|
||||
searchService.sendQuery(inputText, setControllerResults);
|
||||
//searchService.sendQuery(inputText, setControllerResults);
|
||||
searchService.query(inputText).then(function (results) {
|
||||
//console.log('controller - results', results);
|
||||
fullResults = results;
|
||||
$scope.results = results.slice(0, numResults);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
@ -87,7 +95,7 @@ define(function () {
|
||||
* Checks to see if there are more search results to display.
|
||||
*/
|
||||
areMore: function () {
|
||||
return numResults < searchService.getNumResults();
|
||||
return numResults < fullResults.length;//searchService.getNumResults();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -96,7 +104,8 @@ define(function () {
|
||||
*/
|
||||
loadMore: function () {
|
||||
numResults += LOAD_INCREMENT;
|
||||
searchService.refresh(setControllerResults);
|
||||
$scope.results = fullResults.slice(0, numResults);
|
||||
//searchService.refresh(setControllerResults);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -108,13 +108,15 @@ define(
|
||||
// Processes results from the format that elasticsearch returns to
|
||||
// a list of search result objects (that contain domain objects)
|
||||
function processResults(rawResults, timestamp) {
|
||||
var results = rawResults.hits.hits,
|
||||
var results = rawResults.data.hits.hits,
|
||||
resultsLength = results.length,
|
||||
ids = [],
|
||||
scores = {},
|
||||
searchResults = [],
|
||||
i;
|
||||
|
||||
//console.log('es provider - raw results', rawResults);
|
||||
|
||||
/*
|
||||
if (rawResults.data.hits.total > resultsLength) {
|
||||
// TODO: Somehow communicate this to the user
|
||||
@ -133,11 +135,15 @@ define(
|
||||
scores[ids[i]] = results[i][SCORE];
|
||||
}
|
||||
|
||||
//console.log('es provider - ids', ids);
|
||||
|
||||
// Get the domain objects from their IDs
|
||||
return objectService.getObjects(ids).then(function (objects) {
|
||||
var j,
|
||||
id;
|
||||
|
||||
//console.log('es provider - objects', objects);
|
||||
|
||||
for (j = 0; j < resultsLength; j += 1) {
|
||||
id = ids[j];
|
||||
|
||||
@ -154,6 +160,9 @@ define(
|
||||
|
||||
latestResults = searchResults;
|
||||
lastSearchTimestamp = timestamp;
|
||||
|
||||
//console.log('es provider - search results', searchResults);
|
||||
|
||||
return searchResults;
|
||||
});
|
||||
}
|
||||
@ -185,11 +194,12 @@ define(
|
||||
return $http({
|
||||
method: "GET",
|
||||
url: esQuery
|
||||
}).success(function (data, status) {
|
||||
}).then(function (rawResults) {
|
||||
// ...then process the data
|
||||
return processResults(data, timestamp);
|
||||
return processResults(rawResults, timestamp);
|
||||
});
|
||||
} else {
|
||||
//console.log('es provider - empty search input');
|
||||
latestResults = [];
|
||||
lastSearchTimestamp = timestamp;
|
||||
return latestResults;
|
||||
|
@ -38,17 +38,21 @@ define(
|
||||
* the filetree without using external search implementations.
|
||||
*
|
||||
* @constructor
|
||||
* @param $q
|
||||
* @param {ObjectService} objectService the service from which
|
||||
* domain objects can be gotten.
|
||||
* @param {WorkerService} workerService the service which allows
|
||||
* more easy creation of web workers.
|
||||
* @param {roots[]} roots an array of all the root domain objects.
|
||||
*/
|
||||
function GenericSearchProvider(objectService, workerService, roots) {
|
||||
function GenericSearchProvider($q, objectService, workerService, roots) {
|
||||
var worker = workerService.run('genericSearchWorker'),
|
||||
latestResults = [],
|
||||
lastSearchTimestamp = 0;
|
||||
|
||||
lastSearchTimestamp = 0,
|
||||
pendingQueries = {};
|
||||
// pendingQueries is a dictionary with the key value pairs st
|
||||
// the key is the timestamp and the value is the promise
|
||||
|
||||
// Tell the web worker to add a domain object's model to its list of items.
|
||||
function indexItem(domainObject) {
|
||||
var message;
|
||||
@ -103,6 +107,11 @@ define(
|
||||
}
|
||||
// Update the timestamp to the one that this search was made with
|
||||
lastSearchTimestamp = event.data.timestamp;
|
||||
|
||||
//console.log('provider - about to resolve', latestResults);
|
||||
|
||||
// Resove the promise corresponding to this
|
||||
pendingQueries[lastSearchTimestamp].resolve(latestResults);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -153,11 +162,14 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// For documentation, see query below.
|
||||
function queryGeneric(input, timestamp, maxResults, timeout) {
|
||||
function query(input, timestamp, maxResults/*, timeout*/) {
|
||||
var terms = [],
|
||||
searchResults = [],
|
||||
resultsLength;
|
||||
defer = $q.defer();
|
||||
|
||||
pendingQueries[timestamp] = defer;
|
||||
|
||||
// Check to see if the user provided a maximum
|
||||
// number of results to display
|
||||
@ -169,13 +181,15 @@ define(
|
||||
// Instead, assume that the items have already been indexed, and
|
||||
// just send the query to the worker.
|
||||
workerSearch(input, maxResults, timestamp);
|
||||
|
||||
return defer.promise;
|
||||
}
|
||||
|
||||
// Index the tree's contents once at the beginning
|
||||
getItems();
|
||||
// TODO: Is this a good assumption that the tree's contents will not
|
||||
// change often enough?
|
||||
// TODO: This makes the timeout parameter that queryGeneric takes
|
||||
// TODO: This makes the timeout parameter that query takes
|
||||
// useless. See if timing out worker is an idea that works.
|
||||
|
||||
|
||||
@ -202,7 +216,7 @@ define(
|
||||
* @param timeout (optional) the time after which the search should
|
||||
* stop calculations and return partial results
|
||||
*/
|
||||
query: queryGeneric,
|
||||
query: query,
|
||||
|
||||
/**
|
||||
* Get the latest search results that have been calculated. The
|
||||
|
Loading…
Reference in New Issue
Block a user