NIHVIVO-2411 Factor out the execution of a Solr query obtaining the Individuals that correspond to the results.

This commit is contained in:
j2blake 2012-04-18 20:39:13 +00:00
parent d002aff59c
commit 9386832142
2 changed files with 125 additions and 96 deletions

View file

@ -2,25 +2,21 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -165,36 +161,14 @@ public class IndividualListController extends FreemarkerHttpServlet {
} }
} }
// //Pulling out common code that is used for both single (regular) vclass query and multiple (intersection) query
// public static Map<String,Object> getResultsForVClasses(List<String> vclassURIs, int page, String alpha, IndividualDao indDao, ServletContext context)
// throws IOException, ServletException{
// Map<String,Object> rvMap = new HashMap<String,Object>();
// try{
// SolrQuery query = getQuery(vclassURIs, alpha, page, INDIVIDUALS_PER_PAGE);
// rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context);
// List<Individual> individuals = (List<Individual>) rvMap.get("entities");
// if (individuals == null)
// log.debug("entities list is null for vclasses " + vclassURIs.toString() );
// } catch(Throwable th) {
// log.error("An error occurred retrieving results for vclass query", th);
// }
// return rvMap;
// }
@SuppressWarnings("unchecked")
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context) public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, SearchException{ throws SearchException{
Map<String,Object> rvMap = new HashMap<String,Object>(); Map<String,Object> rvMap = new HashMap<String,Object>();
try{ try{
//make query for this rdf:type List<String> classUris = Collections.singletonList(vclassURI);
List<String> classUris = new ArrayList<String>(); IndividualListQueryResults results = buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, context, indDao);
classUris.add(vclassURI); rvMap = getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
SolrQuery query = getQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE); } catch (SolrServerException e) {
rvMap = getResultsForVClassQuery(query, page, INDIVIDUALS_PER_PAGE, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURI );
} catch (ServletException e) {
String msg = "An error occurred retrieving results for vclass query"; String msg = "An error occurred retrieving results for vclass query";
log.error(msg, e); log.error(msg, e);
// Throw this up to processRequest, so the template gets the error message. // Throw this up to processRequest, so the template gets the error message.
@ -205,72 +179,34 @@ public class IndividualListController extends FreemarkerHttpServlet {
return rvMap; return rvMap;
} }
@SuppressWarnings("unchecked") public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context)
throws IOException, ServletException{
Map<String,Object> rvMap = new HashMap<String,Object>(); Map<String,Object> rvMap = new HashMap<String,Object>();
try{ try{
// make query for multiple rdf types IndividualListQueryResults results = buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, context, indDao);
SolrQuery query = getQuery(vclassURIs, alpha, page, pageSize); rvMap = getResultsForVClassQuery(results, page, pageSize, alpha);
log.debug("Executed solr query for " + vclassURIs.toString());
rvMap = getResultsForVClassQuery(query, page, pageSize, alpha, indDao, context);
List<Individual> individuals = (List<Individual>) rvMap.get("entities");
if (individuals == null)
log.debug("entities list is null for vclass " + vclassURIs.toString() );
} catch(Throwable th) { } catch(Throwable th) {
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th); log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
} }
return rvMap; return rvMap;
} }
/** private static IndividualListQueryResults buildAndExecuteVClassQuery(
* This method is now called in a couple of places. It should be refactored List<String> vclassURIs, String alpha, int page, int pageSize,
* into a DAO or similar object. ServletContext context, IndividualDao indDao)
*/ throws SolrServerException {
protected static Map<String,Object> getResultsForVClassQuery(SolrQuery query, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) SolrQuery query = getQuery(vclassURIs, alpha, page, pageSize);
throws IOException, ServletException { IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context);
log.debug("Executed solr query for " + vclassURIs);
if (results.getIndividuals().isEmpty()) {
log.debug("entities list is null for vclass " + vclassURIs);
}
return results;
}
private static Map<String,Object> getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
Map<String,Object> rvMap = new HashMap<String,Object>(); Map<String,Object> rvMap = new HashMap<String,Object>();
SolrServer solr = SolrSetup.getSolrServer(context);
QueryResponse response = null;
// Execute query for individuals of the specified type
try {
response = solr.query(query);
} catch (Throwable t) {
log.error(t, t);
}
if ( response == null ) {
throw new ServletException("Could not run search in IndividualListController");
}
SolrDocumentList docs = response.getResults();
if (docs == null) {
throw new ServletException("Could not run search in IndividualListController");
}
// get list of individuals for the search results
long hitCount = docs.getNumFound();
log.debug("Number of search results: " + hitCount);
Iterator<SolrDocument> docIter = docs.iterator();
List<Individual> individuals = new ArrayList<Individual>(docs.size());
while ( docIter.hasNext() ){
SolrDocument doc = docIter.next();
if (doc != null) {
String uri = doc.get(VitroSearchTermNames.URI).toString();
Individual individual = indDao.getIndividualByURI( uri );
if (individual != null) {
individuals.add( individual );
log.debug("Adding individual " + uri + " to individual list display");
} else {
log.debug("No existing individual for search document with uri = " + uri);
}
}
}
long hitCount = results.getHitCount();
if ( hitCount > pageSize ){ if ( hitCount > pageSize ){
rvMap.put("showPages", Boolean.TRUE); rvMap.put("showPages", Boolean.TRUE);
List<PageRecord> pageRecords = makePagesList(hitCount, pageSize, page); List<PageRecord> pageRecords = makePagesList(hitCount, pageSize, page);
@ -281,9 +217,8 @@ public class IndividualListController extends FreemarkerHttpServlet {
} }
rvMap.put("alpha",alpha); rvMap.put("alpha",alpha);
rvMap.put("totalCount", hitCount); rvMap.put("totalCount", hitCount);
rvMap.put("entities",individuals); rvMap.put("entities", results.getIndividuals());
return rvMap; return rvMap;
} }
@ -337,17 +272,13 @@ public class IndividualListController extends FreemarkerHttpServlet {
} }
private static String makeMultiClassQuery( List<String> vclassUris){ private static String makeMultiClassQuery( List<String> vclassUris){
String queryText = "";
List<String> queryTypes = new ArrayList<String>(); List<String> queryTypes = new ArrayList<String>();
try { try {
// query term for rdf:type - multiple types possible // query term for rdf:type - multiple types possible
for(String vclassUri: vclassUris) { for(String vclassUri: vclassUris) {
queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" "); queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" ");
} }
if (queryTypes.size() > 0) { return StringUtils.join(queryTypes, " AND ");
queryText = StringUtils.join(queryTypes, " AND ");
}
return queryText;
} catch (Exception ex){ } catch (Exception ex){
log.error("Could not make Solr query",ex); log.error("Could not make Solr query",ex);
return ""; return "";

View file

@ -0,0 +1,98 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
/**
* Holds the Individuals that were found in a Solr search query.
*
* Provides a convenience method to run the query and to find the Individuals.
*/
public class IndividualListQueryResults {
private static final Log log = LogFactory
.getLog(IndividualListQueryResults.class);
private static final IndividualListQueryResults EMPTY_RESULT = new IndividualListQueryResults(
0, new ArrayList<Individual>());
// ----------------------------------------------------------------------
// Convenience method
// ----------------------------------------------------------------------
public static IndividualListQueryResults runQuery(SolrQuery query,
IndividualDao indDao, ServletContext context)
throws SolrServerException {
SolrServer solr = SolrSetup.getSolrServer(context);
QueryResponse response = null;
response = solr.query(query);
if (response == null) {
log.debug("response from search query was null");
return EMPTY_RESULT;
}
SolrDocumentList docs = response.getResults();
if (docs == null) {
log.debug("results from search query response was null");
return EMPTY_RESULT;
}
// get list of individuals for the search results
long hitCount = docs.getNumFound();
log.debug("Number of search results: " + hitCount);
List<Individual> individuals = new ArrayList<Individual>(docs.size());
for (SolrDocument doc : docs) {
String uri = doc.get(VitroSearchTermNames.URI).toString();
Individual individual = indDao.getIndividualByURI(uri);
if (individual == null) {
log.debug("No individual for search document with uri = " + uri);
} else {
individuals.add(individual);
log.debug("Adding individual " + uri + " to individual list");
}
}
return new IndividualListQueryResults((int) hitCount, individuals);
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
private final int hitCount;
private final List<Individual> individuals;
public IndividualListQueryResults(int hitCount, List<Individual> individuals) {
this.hitCount = hitCount;
this.individuals = individuals;
}
public int getHitCount() {
return hitCount;
}
public List<Individual> getIndividuals() {
return individuals;
}
}