VIVO-208: all fields now displayed when custom forms are rendered; customized 2-stage forms will still work as before
This commit is contained in:
parent
578bc95b63
commit
37142c0231
2 changed files with 143 additions and 88 deletions
|
@ -33,7 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
|
|||
|
||||
/**
|
||||
* AutocompleteController generates autocomplete content
|
||||
* via the search index.
|
||||
* via the search index.
|
||||
*/
|
||||
|
||||
public class AutocompleteController extends VitroAjaxController {
|
||||
|
@ -49,7 +49,7 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
|
||||
|
||||
String NORESULT_MSG = "";
|
||||
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
|
||||
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
|
||||
|
||||
public static final int MAX_QUERY_LENGTH = 500;
|
||||
|
||||
|
@ -57,50 +57,50 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
protected Actions requiredActions(VitroRequest vreq) {
|
||||
return SimplePermission.USE_BASIC_AJAX_CONTROLLERS.ACTIONS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doRequest(VitroRequest vreq, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
|
||||
String qtxt = vreq.getParameter(PARAM_QUERY);
|
||||
|
||||
SolrQuery query = getQuery(qtxt, vreq);
|
||||
|
||||
SolrQuery query = getQuery(qtxt, vreq);
|
||||
if (query == null ) {
|
||||
log.debug("query for '" + qtxt +"' is null.");
|
||||
doNoQuery(response);
|
||||
return;
|
||||
}
|
||||
log.debug("query for '" + qtxt +"' is " + query.toString());
|
||||
|
||||
|
||||
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
|
||||
QueryResponse queryResponse = solr.query(query);
|
||||
|
||||
if ( queryResponse == null) {
|
||||
log.error("Query response for a search was null");
|
||||
log.error("Query response for a search was null");
|
||||
doNoSearchResults(response);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SolrDocumentList docs = queryResponse.getResults();
|
||||
|
||||
if ( docs == null) {
|
||||
log.error("Docs for a search was null");
|
||||
log.error("Docs for a search was null");
|
||||
doNoSearchResults(response);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
long hitCount = docs.getNumFound();
|
||||
log.debug("Total number of hits = " + hitCount);
|
||||
if ( hitCount < 1 ) {
|
||||
if ( hitCount < 1 ) {
|
||||
doNoSearchResults(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
List<SearchResult> results = new ArrayList<SearchResult>();
|
||||
for (SolrDocument doc : docs) {
|
||||
try {
|
||||
try {
|
||||
String uri = doc.get(VitroSearchTermNames.URI).toString();
|
||||
// RY 7/1/2011
|
||||
// Comment was: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() returns a list.
|
||||
|
@ -116,61 +116,71 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
} else {
|
||||
name = (String) nameRaw;
|
||||
}
|
||||
SearchResult result = new SearchResult(name, uri);
|
||||
|
||||
Object mostSpecificType = doc.get(VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS);
|
||||
String mst = null;
|
||||
if (mostSpecificType instanceof List<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> mstList = (List<String>) mostSpecificType;
|
||||
mst = mstList.get(0);
|
||||
} else {
|
||||
mst = (String) mostSpecificType;
|
||||
}
|
||||
|
||||
SearchResult result = new SearchResult(name, uri, mst);
|
||||
results.add(result);
|
||||
log.debug("results = " + results.toString());
|
||||
} catch(Exception e){
|
||||
log.error("problem getting usable individuals from search " +
|
||||
"hits" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(results);
|
||||
|
||||
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (SearchResult result : results) {
|
||||
jsonArray.put(result.toMap());
|
||||
}
|
||||
response.getWriter().write(jsonArray.toString());
|
||||
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.error(e, e);
|
||||
log.error(e, e);
|
||||
doSearchError(response);
|
||||
}
|
||||
}
|
||||
|
||||
private SolrQuery getQuery(String queryStr, VitroRequest vreq) {
|
||||
|
||||
|
||||
if ( queryStr == null) {
|
||||
log.error("There was no parameter '"+ PARAM_QUERY
|
||||
+"' in the request.");
|
||||
log.error("There was no parameter '"+ PARAM_QUERY
|
||||
+"' in the request.");
|
||||
return null;
|
||||
} else if( queryStr.length() > MAX_QUERY_LENGTH ) {
|
||||
log.debug("The search was too long. The maximum " +
|
||||
"query length is " + MAX_QUERY_LENGTH );
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
SolrQuery query = new SolrQuery();
|
||||
query.setStart(0)
|
||||
.setRows(DEFAULT_MAX_HIT_COUNT);
|
||||
|
||||
.setRows(DEFAULT_MAX_HIT_COUNT);
|
||||
setNameQuery(query, queryStr, vreq);
|
||||
|
||||
// Filter by type
|
||||
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
|
||||
String multipleTypesParam = (String) vreq.getParameter(PARAM_MULTIPLE_RDFTYPE);
|
||||
if (typeParam != null) {
|
||||
addFilterQuery(query, typeParam, multipleTypesParam);
|
||||
}
|
||||
|
||||
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI); // fields to retrieve
|
||||
|
||||
}
|
||||
|
||||
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS); // fields to retrieve
|
||||
|
||||
// Can't sort on multivalued field, so we sort the results in Java when we get them.
|
||||
// query.setSortField(VitroSearchTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
|
||||
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
private void addFilterQuery(SolrQuery query, String typeParam, String multipleTypesParam) {
|
||||
if(multipleTypesParam == null || multipleTypesParam.equals("null") || multipleTypesParam.isEmpty()) {
|
||||
//Single type parameter, process as usual
|
||||
|
@ -181,15 +191,13 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
int len = typeParams.length;
|
||||
int i;
|
||||
List<String> filterQueries = new ArrayList<String>();
|
||||
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
filterQueries.add(VitroSearchTermNames.RDFTYPE + ":\"" + typeParams[i] + "\" ");
|
||||
}
|
||||
String filterQuery = StringUtils.join(filterQueries, " OR ");
|
||||
query.addFilterQuery(filterQuery);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void setNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
|
||||
|
@ -197,10 +205,9 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
if (StringUtils.isBlank(queryStr)) {
|
||||
log.error("No query string");
|
||||
}
|
||||
|
||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||
String tokenizeParam = (String) request.getParameter("tokenize");
|
||||
boolean tokenize = "true".equals(tokenizeParam);
|
||||
|
||||
|
||||
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
|
||||
// query will not be stemmed. So we don't look at the stem parameter until we get to
|
||||
// setTokenizedNameQuery().
|
||||
|
@ -210,43 +217,43 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
setUntokenizedNameQuery(query, queryStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setTokenizedNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
|
||||
|
||||
/* We currently have no use case for a tokenized, unstemmed autocomplete search field, so the option
|
||||
* has been disabled. If needed in the future, will need to add a new field and field type which
|
||||
* is like AC_NAME_STEMMED but doesn't include the stemmer.
|
||||
String stemParam = (String) request.getParameter("stem");
|
||||
String stemParam = (String) request.getParameter("stem");
|
||||
boolean stem = "true".equals(stemParam);
|
||||
if (stem) {
|
||||
String acTermName = VitroSearchTermNames.AC_NAME_STEMMED;
|
||||
String nonAcTermName = VitroSearchTermNames.NAME_STEMMED;
|
||||
} else {
|
||||
String acTermName = VitroSearchTermNames.AC_NAME_UNSTEMMED;
|
||||
String nonAcTermName = VitroSearchTermNames.NAME_UNSTEMMED;
|
||||
String nonAcTermName = VitroSearchTermNames.NAME_UNSTEMMED;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
String acTermName = VitroSearchTermNames.AC_NAME_STEMMED;
|
||||
String nonAcTermName = VitroSearchTermNames.NAME_STEMMED;
|
||||
String acQueryStr;
|
||||
|
||||
|
||||
if (queryStr.endsWith(" ")) {
|
||||
acQueryStr = makeTermQuery(nonAcTermName, queryStr, true);
|
||||
acQueryStr = makeTermQuery(nonAcTermName, queryStr, true);
|
||||
} else {
|
||||
int indexOfLastWord = queryStr.lastIndexOf(" ") + 1;
|
||||
List<String> terms = new ArrayList<String>(2);
|
||||
|
||||
|
||||
String allButLastWord = queryStr.substring(0, indexOfLastWord);
|
||||
if (StringUtils.isNotBlank(allButLastWord)) {
|
||||
terms.add(makeTermQuery(nonAcTermName, allButLastWord, true));
|
||||
}
|
||||
|
||||
|
||||
String lastWord = queryStr.substring(indexOfLastWord);
|
||||
if (StringUtils.isNotBlank(lastWord)) {
|
||||
terms.add(makeTermQuery(acTermName, lastWord, false));
|
||||
}
|
||||
|
||||
|
||||
acQueryStr = StringUtils.join(terms, " AND ");
|
||||
}
|
||||
|
||||
|
@ -255,26 +262,26 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
|
||||
}
|
||||
|
||||
private void setUntokenizedNameQuery(SolrQuery query, String queryStr) {
|
||||
queryStr = queryStr.trim();
|
||||
private void setUntokenizedNameQuery(SolrQuery query, String queryStr) {
|
||||
queryStr = queryStr.trim();
|
||||
queryStr = makeTermQuery(VitroSearchTermNames.AC_NAME_UNTOKENIZED, queryStr, true);
|
||||
query.setQuery(queryStr);
|
||||
}
|
||||
|
||||
|
||||
private String makeTermQuery(String term, String queryStr, boolean mayContainWhitespace) {
|
||||
if (mayContainWhitespace) {
|
||||
queryStr = "\"" + escapeWhitespaceInQueryString(queryStr) + "\"";
|
||||
}
|
||||
return term + ":" + queryStr;
|
||||
}
|
||||
|
||||
|
||||
private String escapeWhitespaceInQueryString(String queryStr) {
|
||||
// Solr wants whitespace to be escaped with a backslash
|
||||
return queryStr.replaceAll("\\s+", "\\\\ ");
|
||||
}
|
||||
|
||||
|
||||
private void doNoQuery(HttpServletResponse response) throws IOException {
|
||||
// For now, we are not sending an error message back to the client because
|
||||
// For now, we are not sending an error message back to the client because
|
||||
// with the default autocomplete configuration it chokes.
|
||||
doNoSearchResults(response);
|
||||
}
|
||||
|
@ -288,36 +295,46 @@ public class AutocompleteController extends VitroAjaxController {
|
|||
private void doNoSearchResults(HttpServletResponse response) throws IOException {
|
||||
response.getWriter().write("[]");
|
||||
}
|
||||
|
||||
|
||||
public class SearchResult implements Comparable<Object> {
|
||||
private String label;
|
||||
private String uri;
|
||||
|
||||
SearchResult(String label, String uri) {
|
||||
private String msType;
|
||||
|
||||
SearchResult(String label, String uri, String msType) {
|
||||
this.label = label;
|
||||
this.uri = uri;
|
||||
this.msType = msType;
|
||||
}
|
||||
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
public String getJsonLabel() {
|
||||
return JSONObject.quote(label);
|
||||
}
|
||||
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
|
||||
public String getJsonUri() {
|
||||
return JSONObject.quote(uri);
|
||||
}
|
||||
|
||||
public String getMsType() {
|
||||
return msType;
|
||||
}
|
||||
|
||||
public String getJsonMsType() {
|
||||
return JSONObject.quote(msType);
|
||||
}
|
||||
Map<String, String> toMap() {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("label", label);
|
||||
map.put("uri", uri);
|
||||
map.put("msType", msType);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue