From 60e640be6cf41805316167057af2058806559430 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 10 Dec 2013 16:26:38 -0500 Subject: [PATCH] added search spelling suggestions (UI needs work) --- scripts/search/search | 6 ++++- scripts/search/spellcheck | 5 ++++ .../edu/harvard/iq/dataverse/SearchPage.java | 20 ++++++++++++-- .../iq/dataverse/SearchServiceBean.java | 21 ++++++++++++--- .../iq/dataverse/SolrQueryResponse.java | 27 +++++++++++++++++++ .../edu/harvard/iq/dataverse/api/Search.java | 15 ++++++++++- src/main/webapp/search.xhtml | 1 + 7 files changed, 88 insertions(+), 7 deletions(-) create mode 100755 scripts/search/spellcheck create mode 100644 src/main/java/edu/harvard/iq/dataverse/SolrQueryResponse.java diff --git a/scripts/search/search b/scripts/search/search index f0ff3e418aa..7ecdac0dac5 100755 --- a/scripts/search/search +++ b/scripts/search/search @@ -1,2 +1,6 @@ #!/bin/sh -curl 'http://localhost:8080/api/search?q=*' +if [ -z "$1" ]; then + curl 'http://localhost:8080/api/search?q=*' +else + curl "http://localhost:8080/api/search?$1" +fi diff --git a/scripts/search/spellcheck b/scripts/search/spellcheck new file mode 100755 index 00000000000..6ae8fee31c0 --- /dev/null +++ b/scripts/search/spellcheck @@ -0,0 +1,5 @@ +#!/bin/sh +# output: +# "hits",1, +# "misspellingsAndCorrections",["datvrse","dataverse"] +curl -s 'http://localhost:8983/solr/spell?spellcheck=true&wt=json&indent=true&q=datvrse' diff --git a/src/main/java/edu/harvard/iq/dataverse/SearchPage.java b/src/main/java/edu/harvard/iq/dataverse/SearchPage.java index 6e14fdcb3f6..3a7fb92c873 100644 --- a/src/main/java/edu/harvard/iq/dataverse/SearchPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/SearchPage.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.logging.Logger; import javax.ejb.EJB; import javax.faces.view.ViewScoped; @@ -18,6 +19,7 @@ public class SearchPage implements java.io.Serializable { private List datasets = new ArrayList<>(); private List dataverseUsers = new ArrayList<>(); private List dataFiles = new ArrayList<>(); + private List spelling_alternatives = new ArrayList<>(); @EJB SearchServiceBean searchService; @@ -39,14 +41,20 @@ public void search() { datasets = new ArrayList(); query = query == null ? "*" : query; - List searchResults = searchService.search(query); + SolrQueryResponse solrQueryResponse = searchService.search(query); + List searchResults = solrQueryResponse.getSolrSearchResults(); + for (Map.Entry> entry : solrQueryResponse.getSpellingSuggestionsByToken().entrySet()) { + spelling_alternatives.add(entry.getValue().toString()); + } for (SolrSearchResult searchResult : searchResults) { String type = searchResult.getType(); switch (type) { case "dataverses": Dataverse dataverse = dataverseService.find(searchResult.getEntityId()); if (searchResult.getHighlightSnippets() != null) { - /** @todo when does long description truncate? */ + /** + * @todo when does long description truncate? + */ dataverse.setDescription(searchResult.getHighlightSnippets().get(0)); } dataverses.add(dataverse); @@ -124,4 +132,12 @@ public void setDataFiles(List dataFiles) { this.dataFiles = dataFiles; } + public List getSpelling_alternatives() { + return spelling_alternatives; + } + + public void setSpelling_alternatives(List spelling_alternatives) { + this.spelling_alternatives = spelling_alternatives; + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java index 2a8cf704762..5ab01ad7910 100644 --- a/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java @@ -3,8 +3,10 @@ import edu.harvard.iq.dataverse.api.SearchFields; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.logging.Logger; import javax.ejb.Stateless; import javax.inject.Named; @@ -13,6 +15,7 @@ import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.response.SpellCheckResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; @@ -28,7 +31,7 @@ public class SearchServiceBean { private static final Logger logger = Logger.getLogger(SearchServiceBean.class.getCanonicalName()); - public List search(String queryFromUser) { + public SolrQueryResponse search(String queryFromUser) { /** * @todo make "localhost" and port number a config option */ @@ -37,6 +40,7 @@ public List search(String queryFromUser) { solrQuery.setQuery(queryFromUser); solrQuery.setHighlight(true).setHighlightSnippets(1); solrQuery.setParam("hl.fl", SearchFields.DESCRIPTION); + solrQuery.setParam("qt", "/spell"); QueryResponse queryResponse; try { @@ -74,7 +78,18 @@ public List search(String queryFromUser) { solrSearchResult.setType(type); solrSearchResults.add(solrSearchResult); } - return solrSearchResults; - } + Map> spellingSuggestionsByToken = new HashMap<>(); + SpellCheckResponse spellCheckResponse = queryResponse.getSpellCheckResponse(); + if (spellCheckResponse != null) { + List suggestions = spellCheckResponse.getSuggestions(); + for (SpellCheckResponse.Suggestion suggestion : suggestions) { + spellingSuggestionsByToken.put(suggestion.getToken(), suggestion.getAlternatives()); + } + } + SolrQueryResponse solrQueryResponse = new SolrQueryResponse(); + solrQueryResponse.setSolrSearchResults(solrSearchResults); + solrQueryResponse.setSpellingSuggestionsByToken(spellingSuggestionsByToken); + return solrQueryResponse; + } } diff --git a/src/main/java/edu/harvard/iq/dataverse/SolrQueryResponse.java b/src/main/java/edu/harvard/iq/dataverse/SolrQueryResponse.java new file mode 100644 index 00000000000..a193d4ba99c --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/SolrQueryResponse.java @@ -0,0 +1,27 @@ +package edu.harvard.iq.dataverse; + +import java.util.List; +import java.util.Map; + +public class SolrQueryResponse { + + private List solrSearchResults; + private Map> spellingSuggestionsByToken; + + public List getSolrSearchResults() { + return solrSearchResults; + } + + public void setSolrSearchResults(List solrSearchResults) { + this.solrSearchResults = solrSearchResults; + } + + public Map> getSpellingSuggestionsByToken() { + return spellingSuggestionsByToken; + } + + public void setSpellingSuggestionsByToken(Map> spellingSuggestionsByToken) { + this.spellingSuggestionsByToken = spellingSuggestionsByToken; + } + +} diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Search.java b/src/main/java/edu/harvard/iq/dataverse/api/Search.java index 5fafc57ccad..3dc94b26926 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Search.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Search.java @@ -2,12 +2,15 @@ import edu.harvard.iq.dataverse.SolrSearchResult; import edu.harvard.iq.dataverse.SearchServiceBean; +import edu.harvard.iq.dataverse.SolrQueryResponse; import java.util.List; +import java.util.Map; import java.util.logging.Logger; import javax.ejb.EJB; import javax.json.Json; import javax.json.JsonArrayBuilder; import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; @@ -24,14 +27,24 @@ public class Search { // public JsonObject search(@QueryParam("q") String query) { public String search(@QueryParam("q") String query) { if (query != null) { - List solrSearchResults = searchService.search(query); + SolrQueryResponse solrQueryResponse = searchService.search(query); + JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder(); + List solrSearchResults = solrQueryResponse.getSolrSearchResults(); for (SolrSearchResult solrSearchResult : solrSearchResults) { filesArrayBuilder.add(solrSearchResult.toJsonObject()); + } + + JsonObjectBuilder spelling_alternatives = Json.createObjectBuilder(); + for (Map.Entry> entry : solrQueryResponse.getSpellingSuggestionsByToken().entrySet()) { + spelling_alternatives.add(entry.getKey(), entry.getValue().toString()); + } + JsonObject value = Json.createObjectBuilder() .add("total_count", solrSearchResults.size()) .add("items", solrSearchResults.toString()) + .add("spelling_alternatives", spelling_alternatives) .add("itemsJson", filesArrayBuilder.build()) .build(); logger.info("value: " + value); diff --git a/src/main/webapp/search.xhtml b/src/main/webapp/search.xhtml index 8e9d955b458..c2938a5f5e7 100644 --- a/src/main/webapp/search.xhtml +++ b/src/main/webapp/search.xhtml @@ -47,6 +47,7 @@ +