diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java index 86651fa1a..eb7f79cd3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SolrJsonServlet.java @@ -184,14 +184,14 @@ public class SolrJsonServlet extends VitroHttpServlet { VClass vclass=null; JSONObject rObj = new JSONObject(); - Map map = getSolrVclassIntersectionResults(vclassURIs, vreq, context); + Map map = getSolrVClassIntersectionResults(vclassURIs, vreq, context); //last parameter indicates single vclass instead of multiple vclasses - rObj = processVclassResults(map, vreq, context, false); + rObj = processVClassResults(map, vreq, context, false); return rObj; } - //Accepts multiple vclasses and returns individuals which correspond to the intersection of those classes (i.e. have all those types) + // Accepts multiple vclasses and returns individuals which correspond to the intersection of those classes (i.e. have all those types) private void getSolrIndividualsByVClasses( HttpServletRequest req, HttpServletResponse resp ){ String errorMessage = null; JSONObject rObj = null; @@ -199,8 +199,7 @@ public class SolrJsonServlet extends VitroHttpServlet { VitroRequest vreq = new VitroRequest(req); VClass vclass=null; - //Could have multiple vclass Ids sent in - List vclassIds = new ArrayList(); + // Could have multiple vclass ids sent in String[] vitroClassIdStr = vreq.getParameterValues("vclassId"); if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){ for(String vclassId: vitroClassIdStr) { @@ -214,7 +213,7 @@ public class SolrJsonServlet extends VitroHttpServlet { log.debug("parameter vclassId URI parameter expected "); throw new Exception("parameter vclassId URI parameter expected "); } - vclassIds = Arrays.asList(vitroClassIdStr); + List vclassIds = Arrays.asList(vitroClassIdStr); rObj = getSolrIndividualsByVClasses(vclassIds,req, getServletContext()); }catch(Exception ex){ errorMessage = ex.toString(); @@ -245,19 +244,17 @@ public class SolrJsonServlet extends VitroHttpServlet { public static JSONObject getSolrIndividualsByVClasses(List vclassURIs, HttpServletRequest req, ServletContext context) throws Exception { VitroRequest vreq = new VitroRequest(req); - Map map = getSolrVclassIntersectionResults(vclassURIs, vreq, context); - JSONObject rObj = processVclassResults(map, vreq, context, true); + Map map = getSolrVClassIntersectionResults(vclassURIs, vreq, context); + JSONObject rObj = processVClassResults(map, vreq, context, true); return rObj; } //Including version for Solr query for Vclass Intersections - private static Map getSolrVclassIntersectionResults(List vclassURIs, VitroRequest vreq, ServletContext context){ + private static Map getSolrVClassIntersectionResults(List vclassURIs, VitroRequest vreq, ServletContext context){ String alpha = SolrIndividualListController.getAlphaParameter(vreq); int page = SolrIndividualListController.getPageParameter(vreq); Map map = null; try { - //TODO: This needs to be moved or copied to Solr Individual List Controller - //Note the method below does use Solr search map = SolrIndividualListController.getResultsForVClassIntersections( vclassURIs, page, @@ -273,37 +270,10 @@ public class SolrJsonServlet extends VitroHttpServlet { //Factoring out to allow for results to be processed from query for both lucene and solr //Map given to process method includes the actual individuals returned from the search - public static JSONObject processVclassResults(Map map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{ + public static JSONObject processVClassResults(Map map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{ JSONObject rObj = DataGetterUtils.processVclassResultsJSON(map, vreq, multipleVclasses); return rObj; } - - - private static String getVClassName(Individual ind, String moniker, - WebappDaoFactory fullWdf) { - /* so the moniker frequently has a vclass name in it. Try to return - * the vclass name that is the same as the moniker so that the templates - * can detect this. */ - if( (moniker == null || moniker.isEmpty()) ){ - if( ind.getVClass() != null && ind.getVClass().getName() != null ) - return ind.getVClass().getName(); - else - return ""; - } - - List vcList = ind.getVClasses(); - for( VClass vc : vcList){ - if( vc != null && moniker.equals( vc.getName() )) - return moniker; - } - - // if we get here, then we didn't find a moniker that matched a vclass, - // so just return any vclass.name - if( ind.getVClass() != null && ind.getVClass().getName() != null ) - return ind.getVClass().getName(); - else - return ""; - } static String getDataPropertyValue(Individual ind, DataProperty dp, WebappDaoFactory wdf){ List values = wdf.getDataPropertyStatementDao() diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java index a36d93813..d22f3e4f5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/SolrIndividualListController.java @@ -43,9 +43,9 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(SolrIndividualListController.class.getName()); - public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000; - public static final int INDIVIDUALS_PER_PAGE = 30; - public static final int MAX_PAGES = 40; //must be even + private static final int INDIVIDUAL_LIST_CONTROLLER_MAX_RESULTS = 30000; + private static final int INDIVIDUALS_PER_PAGE = 30; + private static final int MAX_PAGES = 40; // must be even private static final String TEMPLATE_DEFAULT = "individualList.ftl"; @@ -167,7 +167,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { throws IOException, ServletException{ Map rvMap = new HashMap(); try{ - SolrQuery query = getQuery(vclassURIs, alpha, page); + SolrQuery query = getQuery(vclassURIs, alpha); rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); List individuals = (List) rvMap.get("entities"); if (individuals == null) @@ -185,7 +185,7 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { //make query for this rdf:type List classUris = new ArrayList(); classUris.add(vclassURI); - SolrQuery query = getQuery(classUris, alpha, page); + SolrQuery query = getQuery(classUris, alpha); rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); List individuals = (List) rvMap.get("entities"); if (individuals == null) @@ -201,14 +201,13 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { Map rvMap = new HashMap(); try{ // make query for multiple rdf types - SolrQuery query = getQuery(vclassURIs, alpha, page); - //get results corresponding to this query + SolrQuery query = getQuery(vclassURIs, alpha); rvMap = getResultsForVClassQuery(query, page, alpha, indDao, context); List individuals = (List) rvMap.get("entities"); if (individuals == null) log.debug("entities list is null for vclass " + vclassURIs.toString() ); } 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; } @@ -231,33 +230,42 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { } if ( response == null ) { - throw new ServletException("Could not run search in IndividualListController"); + throw new ServletException("Could not run search in SolrIndividualListController"); } SolrDocumentList docs = response.getResults(); if (docs == null) { - throw new ServletException("Could not run search in IndividualListController"); + throw new ServletException("Could not run search in SorlIndividualListController"); } // get list of individuals for the search results - long size = docs.getNumFound(); - log.debug("Number of search results: " + size); + long hitCount = docs.getNumFound(); + log.debug("Number of search results: " + hitCount); - List individuals = new ArrayList(); - for (SolrDocument doc : docs) { - String uri = doc.get(VitroSearchTermNames.URI).toString(); - Individual individual = indDao.getIndividualByURI( uri ); - if (individual != null) { - individuals.add(individual); - } + List individuals = new ArrayList(INDIVIDUALS_PER_PAGE); + int individualsAdded = 0; + int index = (page-1) * INDIVIDUALS_PER_PAGE; + while (individualsAdded < INDIVIDUALS_PER_PAGE && index < hitCount) { + SolrDocument doc = docs.get(index); + if (doc != null) { + String uri = doc.get(VitroSearchTermNames.URI).toString(); + Individual individual = indDao.getIndividualByURI( uri ); + if (individual != null) { + individualsAdded++; + individuals.add(individual); + log.debug("Adding individual " + uri + " to individuals for display"); + } else { + log.debug("No existing individual for search document with uri = " + uri); + } + } + index++; } - - rvMap.put("count", size); - if( size > INDIVIDUALS_PER_PAGE ){ + // Test index < hitCount ensures that there are still some docs left + if ( hitCount > INDIVIDUALS_PER_PAGE && index < hitCount ){ rvMap.put("showPages", Boolean.TRUE); - List pageRecords = makePagesList(size, INDIVIDUALS_PER_PAGE, page); + List pageRecords = makePagesList(hitCount, INDIVIDUALS_PER_PAGE, page); rvMap.put("pages", pageRecords); }else{ rvMap.put("showPages", Boolean.FALSE); @@ -266,45 +274,47 @@ public class SolrIndividualListController extends FreemarkerHttpServlet { rvMap.put("alpha",alpha); - rvMap.put("totalCount", size); + rvMap.put("totalCount", hitCount); rvMap.put("entities",individuals); return rvMap; } - private static SolrQuery getQuery(List vclassUris, String alpha, int page){ - // Solr requires these values, but we don't want them to be the real values for this page - // of results, else the refinement links won't work correctly: each page of results needs to - // show refinement links generated for all results, not just for the results on the current page. - + private static SolrQuery getQuery(List vclassUris, String alpha){ + String queryText = ""; - //Query text should be of form: + List queryTypes = new ArrayList(); - try{ - //query term for rdf:type - multiple types possible + try { + + // query term for rdf:type - multiple types possible for(String vclassUri: vclassUris) { queryTypes.add(VitroSearchTermNames.RDFTYPE + ":\"" + vclassUri + "\" "); } - if(queryTypes.size() > 1) { + if (queryTypes.size() > 0) { queryText = StringUtils.join(queryTypes, " AND "); - } else { - if(queryTypes.size() > 0) { - queryText = queryTypes.get(0); - } - } + } - // Add alpha filter if it is needed - if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) { - queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*"; - } - SolrQuery query = new SolrQuery(queryText); - log.debug("Query text is " + queryText); - int start = (page-1)*INDIVIDUALS_PER_PAGE; - query.setStart(start) - .setRows(INDIVIDUALS_PER_PAGE) - .setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc); + // Add alpha filter if applicable + if ( alpha != null && !"".equals(alpha) && alpha.length() == 1) { + queryText += VitroSearchTermNames.NAME_LOWERCASE + ":" + alpha.toLowerCase() + "*"; + } + + SolrQuery query = new SolrQuery(queryText); + log.debug("Query text is " + queryText); + + // Get all available results from index rather than just those for the current page. + // Otherwise, if there are a large number of non-existent individuals in the search + // index, the current page of results might not retrieve any existing individuals, + // and nothing gets returned. + query.setStart(0) + .setRows(INDIVIDUAL_LIST_CONTROLLER_MAX_RESULTS) + // Need a single-valued field for sorting + .setSortField(VitroSearchTermNames.NAME_LOWERCASE_SINGLE_VALUED, SolrQuery.ORDER.asc); + return query; + } catch (Exception ex){ log.error(ex,ex); return new SolrQuery(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java index 621da6dea..781b363b2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/SolrAutocompleteController.java @@ -91,7 +91,7 @@ public class SolrAutocompleteController extends VitroAjaxController { } long hitCount = docs.getNumFound(); - log.debug("Number of hits = " + hitCount); + log.debug("Total number of hits = " + hitCount); if ( hitCount < 1 ) { doNoSearchResults(response); return;