diff --git a/FUSION_CONFIG.sample.js b/FUSION_CONFIG.sample.js index 902d5e9e..2fba54f9 100644 --- a/FUSION_CONFIG.sample.js +++ b/FUSION_CONFIG.sample.js @@ -63,6 +63,15 @@ appConfig = { //eslint-disable-line query_profile_id: 'default', use_query_profile: true, // Force use of query-profile + // The name of the recommender pipeline you want to use + recommender_pipeline_id: 'related_items', + + // The field you want to recommend on + recommender_field: 'body', + + // The Name of the Field you will be using to supply your ids + recommender_id_field: 'id', + // Search UI Title // This title appears in a number of places in the app, including page title. // In the header it is replaced by the logo if one is provided. diff --git a/client/assets/components/documentList/_documentList.scss b/client/assets/components/documentList/_documentList.scss index bf6cb6ee..cc3bae9a 100644 --- a/client/assets/components/documentList/_documentList.scss +++ b/client/assets/components/documentList/_documentList.scss @@ -1,3 +1,11 @@ #documentList{ em{ background-color:$highlight-color;} } + +.moreLikeThisText { + visibility: visible; + zoom: 1; + border: 1px solid black; + overflow-x:auto; + overflow-y:auto; +} \ No newline at end of file diff --git a/client/assets/components/documentList/documentList.html b/client/assets/components/documentList/documentList.html index 49e06c4e..7e3bf0f8 100644 --- a/client/assets/components/documentList/documentList.html +++ b/client/assets/components/documentList/documentList.html @@ -1,6 +1,18 @@
- + + Related Items +
+
+
{{test.title}}
+
+
+ + diff --git a/client/assets/components/documentList/documentList.js b/client/assets/components/documentList/documentList.js index 79dc266c..d94d79f2 100644 --- a/client/assets/components/documentList/documentList.js +++ b/client/assets/components/documentList/documentList.js @@ -21,7 +21,7 @@ } - function Controller($sce, $log, $anchorScroll, Orwell) { + function Controller($sce, $log, $anchorScroll, Orwell, QueryDataService, ConfigService) { 'ngInject'; var vm = this; vm.docs = []; @@ -31,11 +31,19 @@ vm.toggleGroupedResults = toggleGroupedResults; vm.showGroupedResults = {}; vm.getDocPosition = getDocPosition; + vm.getMoreLikeThisFromObservable = getMoreLikeThisFromObservable; + vm.getMoreLikeThis = getMoreLikeThis; + vm.overlay = overlay; activate(); //////// + function overlay() { + var el = document.getElementById("overlay"); + el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible"; + } + function activate() { var resultsObservable = Orwell.getObservable('queryResults'); resultsObservable.addObserver(function (data) { @@ -142,5 +150,123 @@ function getDocPosition(doc, docs){ return _.findIndex(docs, doc); } + + /* + * Manipulates the mlt results to make them more readable in the css + * @returns String parsedMoreLikeThisResults String to supply the html + */ + function manipulateResults() { + var parsedMoreLikeThisResults = ""; + var rawMoreLikeThisResults; + + try { + rawMoreLikeThisResults = Orwell.getObservable('mltResults').content.response.docs; + } + catch (err) { + $log.debug(err); + if (err.name === 'TypeError'){ + $log.error(err); + return "There was an Error querying Fusion. Check your defaults" ; + } + else { + $log.error(err); + return "Something went wrong!"; + } + } + // If there are no results this means something about the parameters was off + if (rawMoreLikeThisResults.length == 0) { + return "There are no Related Items that fit the provided parameters. Try changing some of the parameters in your query pipeline"; + } + + // Otherwise we can go ahead and return what we intended + else { + vm.test = rawMoreLikeThisResults; + for (var resultIndex in rawMoreLikeThisResults) { + var moreLikeThisToParse = rawMoreLikeThisResults[resultIndex]; + var index = parseInt(resultIndex) + 1 + if (moreLikeThisToParse.title != null) { + parsedMoreLikeThisResults += index.toString() + ": " + moreLikeThisToParse.title + "\n"; + } + else{ + parsedMoreLikeThisResults += moreLikeThisToParse.id + "\n"; + } + } + return parsedMoreLikeThisResults; + } + } + + /** + * Get the moreLikethis recommendations from a query pipeline in Fusion. This particular method gets the results from + * an observable that gets populated on page load. + * @param {object} doc Doc of which the id is required to return the appropriate mlt results + * @return {list} moreLikeThisForDoc List of "more like this" responses to the document in question + */ + function getMoreLikeThisFromObservable(doc) { + var mltResultsObservable = Orwell.getObservable('mltResults'); + var docs; + var moreLikeThisForDoc = []; + + if (mltResultsObservable.content == null || mltResultsObservable.content == undefined) { + $log.debug("We have no more like This"); + return moreLikeThisForDoc; + } + + else if (mltResultsObservable.content != null) { + for (var item in mltResultsObservable.content) { + if (item == doc.id) { + docs = mltResultsObservable[item].docs; + break; + } + } + } + if (docs != undefined) { + if (docs.length == 0) { + return "No Related Items Found!" + } + else { + for (var doc in docs){ + moreLikeThisForDoc.push(docs[doc].title); + } + } + } + $log.debug(moreLikeThisForDoc); + return moreLikeThisForDoc; + } + + /** + * Get moreLikeThis recommendations from a query pipeline in fusion. This particular method gets the + * results by launching the mlt search for the particular doc in question and returning the results. + * @param {object} doc Doc of which the id is required to launch the appropriate query + * @return {list} mltResults List of "more Like This" responses to the document in question + */ + function getMoreLikeThis(doc){ + // vm.overlay(); + vm.docId = doc.id; + var idField = ConfigService.getRecommenderIdField(); + if (idField == null) { + $log.debug("We don't have an id field! Setting it to id"); + idField = "id"; + } + + var obj = {}; + obj[idField] = doc.id; + obj['wt'] = 'json'; + + // Clear the innerhtml to prevent a split second confusion + // document.getElementById('MoreLikeThisResultsFromPipeline').innerHTML = ""; + QueryDataService.getMoreLikeThisResults(obj, true).then(displayResults, solrError); + + function solrError(response) { + $log.error(response); + // document.getElementById('MoreLikeThisResultsFromPipeline').innerHTML = response.details; + } + + function displayResults(response){ + // console.log(response.response.docs); + var parsedMoreLikeThisResults = manipulateResults(); + $log.debug("The results are " + parsedMoreLikeThisResults); + // document.getElementById('MoreLikeThisResultsFromPipeline').innerHTML = parsedMoreLikeThisResults; + } + } } })(); diff --git a/client/assets/js/services/ConfigService.js b/client/assets/js/services/ConfigService.js index 609d4401..d3963523 100644 --- a/client/assets/js/services/ConfigService.js +++ b/client/assets/js/services/ConfigService.js @@ -77,6 +77,9 @@ config: appConfig, getFusionUrl: getFusionUrl, getQueryProfile: getQueryProfile, + getRecommenderPipeline: getRecommenderPipeline, + getRecommenderField: getRecommenderField, + getRecommenderIdField: getRecommenderIdField, getCollectionName: getCollectionName, getQueryPipeline: getQueryPipeline, getLoginCredentials: getLoginCredentials, @@ -123,6 +126,18 @@ return appConfig.query_pipeline_id; } + function getRecommenderPipeline() { + return appConfig.recommender_pipeline_id; + } + + function getRecommenderField(){ + return appConfig.recommender_field; + } + + function getRecommenderIdField(){ + return appConfig.recommender_id_field; + } + function getQueryProfile() { return appConfig.query_profile_id; } diff --git a/client/assets/js/services/QueryDataService.js b/client/assets/js/services/QueryDataService.js index 4c113f98..503a7358 100644 --- a/client/assets/js/services/QueryDataService.js +++ b/client/assets/js/services/QueryDataService.js @@ -13,6 +13,8 @@ function Config(OrwellProvider) { 'ngInject'; OrwellProvider.createObservable('queryResults', {}); + OrwellProvider.createObservable('mltResults', {}); + OrwellProvider.createObservable('mltResults2', {}); } function QueryDataService() { @@ -24,10 +26,12 @@ function $get($q, $http, ConfigService, ApiBase, Orwell, QueryBuilder) { 'ngInject'; var queryResultsObservable = Orwell.getObservable('queryResults'); + var mltResultsObservable = Orwell.getObservable('mltResults'); return { getQueryResults: getQueryResults, getProfileEndpoint: getProfileEndpoint, - getPipelineEndpoint: getPipelineEndpoint + getPipelineEndpoint: getPipelineEndpoint, + getMoreLikeThisResults: getMoreLikeThisResults }; /** @@ -41,7 +45,6 @@ var deferred = $q.defer(); var queryString = QueryBuilder.objectToURLString(query); - var fullUrl = getQueryUrl(ConfigService.getIfQueryProfile()) + '?' + queryString; $http @@ -65,6 +68,46 @@ return deferred.promise; } + /** + * Make a query to the query profiles endpoint + * @param {object} query Should have all the query params, like + * For select?q=query&fq=blah you need to pass in an object + * {'q': 'query', 'fq': 'blah'} + * @param {boolean} object Boolean specifying whether to use the default mlt query pipeline + * or not. + * @return {Promise} Promise that resolve with a Fusion response coming from Solr + */ + function getMoreLikeThisResults(query, pipeline) { + var deferred = $q.defer(); + + var queryString = QueryBuilder.objectToURLString(query); + var fullUrl; + if (pipeline == true) { + fullUrl = getMltQueryUrl(ConfigService.getIfQueryProfile()) + '?' + queryString; + } + else { + fullUrl = getQueryUrl(ConfigService.getIfQueryProfile()) + '?' + queryString; + } + + $http + .get(fullUrl) + .then(success) + .catch(failure); + + function success(response) { + mltResultsObservable.setContent(response.data); + deferred.resolve(response.data); + } + + function failure(err) { + mltResultsObservable.setContent({ + numFound: 0 + }); + deferred.reject(err.data); + } + return deferred.promise; + } + /** * Returns the appropriate base url for an endpoint * @@ -78,6 +121,18 @@ return isProfiles ? profilesEndpoint : pipelinesEndpoint; } + /** + * Returns the appropriate base url for a more like this endpoint, namely the one + * containing the default_mlt pipeline + * + * @param {Boolean} isProfiles Determines which endpoint type to return; + * @return {string} The URL endpoint for the query without parameters. + */ + function getMltQueryUrl(){ + var pipelinesEndpoint = getPipelineEndpoint(ConfigService.getRecommenderPipeline(), 'select'); + return pipelinesEndpoint; + } + function getProfileEndpoint(profile, requestHandler){ return ApiBase.getEndpoint() + 'api/apollo/collections/' + ConfigService.getCollectionName() + '/query-profiles/' + diff --git a/client/assets/js/services/QueryService.js b/client/assets/js/services/QueryService.js index 8463c77f..4e658bb8 100644 --- a/client/assets/js/services/QueryService.js +++ b/client/assets/js/services/QueryService.js @@ -31,7 +31,6 @@ queryObservable.addObserver(function (query) { QueryDataService.getQueryResults(query); - }); return {