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