mirror of
https://github.com/nasa/openmct.git
synced 2025-05-08 11:38:35 +00:00
[Search] Added timestamp to queries
(Temporariliy removed the elasticsearch provider from bundle.json) Added a timestamp parameter to the query so that the aggregator can tell when the results were last updated. Created a separate function for getting the results list. GenericSearch now converts back from models to domain objects after the web worker does its work.
This commit is contained in:
parent
1b5fbccc06
commit
4f4af87285
@ -44,12 +44,6 @@
|
|||||||
"implementation": "providers/GenericSearchProvider.js",
|
"implementation": "providers/GenericSearchProvider.js",
|
||||||
"depends": [ "$rootScope", "$timeout", "objectService", "workerService" ]
|
"depends": [ "$rootScope", "$timeout", "objectService", "workerService" ]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"provides": "searchService",
|
|
||||||
"type": "provider",
|
|
||||||
"implementation": "providers/ElasticsearchSearchProvider.js",
|
|
||||||
"depends": [ "$http", "objectService", "ELASTIC_ROOT" ]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"provides": "searchService",
|
"provides": "searchService",
|
||||||
"type": "aggregator",
|
"type": "aggregator",
|
||||||
|
@ -41,6 +41,7 @@ define(
|
|||||||
* aggregated
|
* aggregated
|
||||||
*/
|
*/
|
||||||
function SearchAggregator(providers) {
|
function SearchAggregator(providers) {
|
||||||
|
var latestMergedResults = [];
|
||||||
|
|
||||||
// Remove extra objects that have the same ID
|
// Remove extra objects that have the same ID
|
||||||
function filterRepeats(results) {
|
function filterRepeats(results) {
|
||||||
@ -138,37 +139,53 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recieves results in the format of a serachResult object. It
|
|
||||||
// has the members id, object, and score. It has a function
|
|
||||||
// next() which returns the next highest score search result
|
|
||||||
// for that search.
|
|
||||||
|
|
||||||
// Calls the searches of each of the providers, then
|
// Calls the searches of each of the providers, then
|
||||||
// merges the results lists so that there are not redundant
|
// merges the results lists so that there are not redundant
|
||||||
// results
|
// results
|
||||||
function mergeResults(inputID) {
|
/**
|
||||||
var resultsPromises = [];
|
*
|
||||||
|
*/
|
||||||
|
function queryAll(inputID) {
|
||||||
|
var resultsPromises = [],
|
||||||
|
date = new Date(),
|
||||||
|
timestamp = date.getTime();
|
||||||
|
|
||||||
// Get result list promises
|
// Get result list promises
|
||||||
|
// TODO: This is now 'Send the query to all the providers'
|
||||||
for (var i = 0; i < providers.length; i += 1) {
|
for (var i = 0; i < providers.length; i += 1) {
|
||||||
resultsPromises.push(
|
resultsPromises.push(
|
||||||
providers[i].query(
|
providers[i].query(
|
||||||
inputID, DEFAULT_MAX_RESULTS, DEFUALT_TIMEOUT
|
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.
|
||||||
|
|
||||||
|
//var newerResults = [];
|
||||||
|
|
||||||
|
|
||||||
// Wait for the promises to fufill
|
// Wait for the promises to fufill
|
||||||
return getPromisedResults(resultsPromises, 0, []).then(function (c) {
|
return getPromisedResults(resultsPromises, 0, []).then(function (c) {
|
||||||
// Get rid of the repeated objects and put in correct order
|
// Get rid of the repeated objects and put in correct order
|
||||||
c = filterRepeats(c);
|
c = filterRepeats(c);
|
||||||
c = orderByScore(c);
|
c = orderByScore(c);
|
||||||
|
latestMergedResults = c;
|
||||||
return c;
|
return c;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: getLatestResults(start, stop) so you can choose which indicies to start and stop
|
||||||
|
// at, which will allow for 'load more' option
|
||||||
|
// may also need to include timestamp stuff in there
|
||||||
|
|
||||||
return {
|
return {
|
||||||
query: mergeResults
|
sendQuery: queryAll,
|
||||||
|
getLatestResults: function (start, stop) {
|
||||||
|
// TODO: Make sure that slice handles out of bounds
|
||||||
|
return latestMergedResults.slice(start, stop);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ define(function () {
|
|||||||
// Will need to compile search result list (for this
|
// Will need to compile search result list (for this
|
||||||
// result page) here, using pseudo linkedlist searchResult
|
// result page) here, using pseudo linkedlist searchResult
|
||||||
|
|
||||||
searchService.query(inputID).then(function (c) {
|
searchService.sendQuery(inputID).then(function (c) {
|
||||||
$scope.results = c;
|
$scope.results = c;
|
||||||
$scope.index = 0;
|
$scope.index = 0;
|
||||||
page($scope.index, $scope.pageLength);
|
page($scope.index, $scope.pageLength);
|
||||||
|
@ -157,12 +157,16 @@ define(
|
|||||||
*
|
*
|
||||||
* @param inputID the name of the ID property of the html text
|
* @param inputID the name of the ID property of the html text
|
||||||
* input where this funcion should find the search term
|
* input where this funcion should find the search term
|
||||||
|
* @param timestamp the time at which this function was called,
|
||||||
|
* this timestamp will be associated with the latest results
|
||||||
|
* list, which allows the aggregator to see if it has been
|
||||||
|
* updated
|
||||||
* @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
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
function queryElasticsearch(inputID, maxResults, timeout) {
|
function queryElasticsearch(inputID, timestamp, maxResults, timeout) {
|
||||||
var searchTerm,
|
var searchTerm,
|
||||||
esQuery;
|
esQuery;
|
||||||
|
|
||||||
|
@ -45,39 +45,8 @@ define(
|
|||||||
*/
|
*/
|
||||||
function GenericSearchProvider($rootScope, $timeout, objectService, workerService) {
|
function GenericSearchProvider($rootScope, $timeout, objectService, workerService) {
|
||||||
var worker = workerService.run('genericSearchWorker'),
|
var worker = workerService.run('genericSearchWorker'),
|
||||||
latestResults = [];
|
latestResults = [],
|
||||||
|
lastSearchTimestamp;
|
||||||
/*
|
|
||||||
function requestItems() {
|
|
||||||
// Aquire My Items (root folder)
|
|
||||||
// I don't think we can do this part in the webworker because of the objectService
|
|
||||||
return objectService.getObjects(['mine']).then(function (objects) {
|
|
||||||
// Get the webworker to go through the tree
|
|
||||||
console.log('about to post');
|
|
||||||
console.log('objects.mine', objects.mine);
|
|
||||||
console.log('objects.mine stringify', JSON.stringify(objects.mine));
|
|
||||||
console.log('objectService', objectService);
|
|
||||||
console.log('objectService stringify', JSON.stringify(objectService));
|
|
||||||
|
|
||||||
// Testing making JSON object
|
|
||||||
var jsonObj = {};
|
|
||||||
var getC = JSON.stringify(objects.mine.getCapability);
|
|
||||||
console.log('empty json', jsonObj);
|
|
||||||
jsonObj = {
|
|
||||||
getCapability: getC,
|
|
||||||
getId: objects.mine.getId,
|
|
||||||
getModel: objects.mine.getModel,
|
|
||||||
hasCapability: objects.mine.hasCapability,
|
|
||||||
useCapability: objects.mine.useCapability
|
|
||||||
};
|
|
||||||
console.log('json', jsonObj);
|
|
||||||
|
|
||||||
worker.postMessage(jsonObj); // Not working :(
|
|
||||||
console.log('posted');
|
|
||||||
});
|
|
||||||
//counter += 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Tell the web worker to add a new item's model to its list of items.
|
// Tell the web worker to add a new item's model to its list of items.
|
||||||
function indexItem(domainObject) {
|
function indexItem(domainObject) {
|
||||||
@ -94,11 +63,12 @@ define(
|
|||||||
// Tell the worker to search for items it has that match this searchInput.
|
// Tell the worker to search for items it has that match this searchInput.
|
||||||
// Takes the searchInput, as well as a max number of results (will return
|
// Takes the searchInput, as well as a max number of results (will return
|
||||||
// less than that if there are fewer matches).
|
// less than that if there are fewer matches).
|
||||||
function workerSearch(searchInput, maxResults) {
|
function workerSearch(searchInput, maxResults, timestamp) {
|
||||||
var message = {
|
var message = {
|
||||||
request: 'search',
|
request: 'search',
|
||||||
input: searchInput,
|
input: searchInput,
|
||||||
maxNumber: maxResults
|
maxNumber: maxResults,
|
||||||
|
timestamp: timestamp
|
||||||
};
|
};
|
||||||
worker.postMessage(message);
|
worker.postMessage(message);
|
||||||
}
|
}
|
||||||
@ -106,17 +76,23 @@ define(
|
|||||||
worker.onmessage = handleResponse;
|
worker.onmessage = handleResponse;
|
||||||
|
|
||||||
function handleResponse(event) {
|
function handleResponse(event) {
|
||||||
//latest = event.data;
|
|
||||||
|
|
||||||
console.log('handleResponse', event.data);
|
console.log('handleResponse', event.data);
|
||||||
if (event.data.request === 'search') {
|
if (event.data.request === 'search') {
|
||||||
latestResults = event.data.results;
|
// Convert the ids given from the web worker into domain objects
|
||||||
console.log('updated latestResults', latestResults);
|
var ids = [];
|
||||||
|
for (var i = 0; i < event.data.results.length; i++) {
|
||||||
|
ids.push(event.data.results[i].id);
|
||||||
|
}
|
||||||
|
objectService.getObjects(ids).then(function (objects) {
|
||||||
|
latestResults = [];
|
||||||
|
for (var i in objects) {
|
||||||
|
latestResults.push(objects[i]);
|
||||||
|
}
|
||||||
|
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
|
// If the message was from 'index', we don't need to do anything
|
||||||
|
|
||||||
//$rootScope.$apply();
|
|
||||||
//requestNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive helper function for getItems()
|
// Recursive helper function for getItems()
|
||||||
@ -164,90 +140,10 @@ define(
|
|||||||
}
|
}
|
||||||
return; // We don't need to return anything anymore
|
return; // We don't need to return anything anymore
|
||||||
// TODO: Fix return statements. Do we need them still?
|
// TODO: Fix return statements. Do we need them still?
|
||||||
/*
|
|
||||||
// Turn them into searchResult objects (object, id, and score)
|
|
||||||
var searchResultItems = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < items.length; i += 1) {
|
|
||||||
// Test out calling worker indexItem
|
|
||||||
indexItem(items[i]);
|
|
||||||
|
|
||||||
searchResultItems.push({
|
|
||||||
id: items[i].getId(),
|
|
||||||
object: items[i],
|
|
||||||
score: 0 // Assign actual score when filtering for term
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log('searchResultItems (in Everything)', searchResultItems);
|
|
||||||
return searchResultItems;
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Process the search input. Makes an array of search terms
|
|
||||||
// by splitting up the input at spaces.
|
|
||||||
function process(input) {
|
|
||||||
return input.toLocaleLowerCase().split(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a score for an item based on its similarity to a search term.
|
|
||||||
// The score is equal to the number of terms that are a substring of the
|
|
||||||
// object name.
|
|
||||||
function score(item, terms, originalInput) {
|
|
||||||
var name = item.object.getModel().name.toLocaleLowerCase(),
|
|
||||||
weight = .65,
|
|
||||||
score = 0;
|
|
||||||
|
|
||||||
// Make the score really big if the item name and
|
|
||||||
// the original search input are the same
|
|
||||||
if (name === originalInput.toLocaleLowerCase()) {
|
|
||||||
score = 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
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++;
|
|
||||||
|
|
||||||
// Add extra to the score if the search term exists
|
|
||||||
// as its own term within the items
|
|
||||||
if (name.split(' ').indexOf(terms[i]) !== -1) {
|
|
||||||
score += .5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return score * weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter through a list of searchResults based on a search term
|
|
||||||
function filterResults(results, originalInput, resultsLength) {
|
|
||||||
var terms,
|
|
||||||
searchResults = [],
|
|
||||||
itemModel;
|
|
||||||
|
|
||||||
// Split the original search input into search terms
|
|
||||||
terms = process(originalInput);
|
|
||||||
|
|
||||||
for (var i = 0; i < resultsLength; i += 1) {
|
|
||||||
// Prevent errors from getModel not being defined
|
|
||||||
if (results[i].object.getModel) {
|
|
||||||
results[i].score = score(results[i], terms, originalInput);
|
|
||||||
// Include any items that match the terms and are of valid type
|
|
||||||
if (results[i].score > 0 && validType(results[i].object.getModel())) {
|
|
||||||
// Add the result to the result list
|
|
||||||
searchResults.push(results[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return searchResults;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches through the filetree for domain objects which match
|
* Searches through the filetree for domain objects which match
|
||||||
* the search term. This function is to be used as a fallback
|
* the search term. This function is to be used as a fallback
|
||||||
@ -261,12 +157,16 @@ define(
|
|||||||
*
|
*
|
||||||
* @param inputID the name of the ID property of the html text
|
* @param inputID the name of the ID property of the html text
|
||||||
* input where this funcion should find the search term
|
* input where this funcion should find the search term
|
||||||
|
* @param timestamp the time at which this function was called,
|
||||||
|
* this timestamp will be associated with the latest results
|
||||||
|
* list, which allows the aggregator to see if it has been
|
||||||
|
* updated
|
||||||
* @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
|
||||||
* @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
|
||||||
*/
|
*/
|
||||||
function queryGeneric(inputID, maxResults, timeout) {
|
function queryGeneric(inputID, timestamp, maxResults, timeout) {
|
||||||
var input,
|
var input,
|
||||||
terms = [],
|
terms = [],
|
||||||
searchResults = [],
|
searchResults = [],
|
||||||
@ -285,9 +185,11 @@ define(
|
|||||||
// Get items list
|
// Get items list
|
||||||
//requestItems(); // Test out the worker
|
//requestItems(); // Test out the worker
|
||||||
return getItems(timeout).then(function (/*searchResultItems*/) {
|
return getItems(timeout).then(function (/*searchResultItems*/) {
|
||||||
var test = workerSearch(input, maxResults);
|
|
||||||
console.log('test', test);
|
|
||||||
|
|
||||||
|
workerSearch(input, maxResults, timestamp);
|
||||||
|
return; // There's nothing we need to return here
|
||||||
|
|
||||||
|
/*
|
||||||
// Wait for latestResults to be not empty, then return
|
// Wait for latestResults to be not empty, then return
|
||||||
function wait(){
|
function wait(){
|
||||||
if (latestResults.length === 0){
|
if (latestResults.length === 0){
|
||||||
@ -301,10 +203,10 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('about to wait');
|
console.log('about to wait');
|
||||||
wait();
|
return wait();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
console.log('returning (not)');
|
|
||||||
//return test;
|
|
||||||
/*
|
/*
|
||||||
// Keep track of the number of results to display
|
// Keep track of the number of results to display
|
||||||
if (searchResultItems.length < maxResults) {
|
if (searchResultItems.length < maxResults) {
|
||||||
|
@ -131,7 +131,8 @@
|
|||||||
|
|
||||||
var message = {
|
var message = {
|
||||||
request: 'search',
|
request: 'search',
|
||||||
results: results
|
results: results,
|
||||||
|
timestamp: data.timestamp
|
||||||
};
|
};
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user