001package org.kuali.ole.docstore.discovery.service; 002 003import org.apache.solr.client.solrj.SolrQuery; 004import org.apache.solr.client.solrj.SolrServer; 005import org.apache.solr.client.solrj.response.QueryResponse; 006import org.apache.solr.common.SolrDocument; 007import org.apache.solr.common.SolrDocumentList; 008import org.kuali.ole.docstore.model.bo.OleDocument; 009import org.kuali.ole.docstore.model.bo.WorkBibDocument; 010import org.kuali.ole.docstore.model.bo.WorkEInstanceDocument; 011import org.kuali.ole.docstore.model.bo.WorkInstanceDocument; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014import java.util.ArrayList; 015import java.util.List; 016import java.util.Map; 017import java.util.Set; 018 019/** 020 * Created with IntelliJ IDEA. 021 * User: ? 022 * Date: 8/6/12 023 * Time: 11:42 AM 024 * To change this template use File | Settings | File Templates. 025 */ 026public class SRUCQLQueryServiceImpl implements SRUCQLQueryService { 027 028 private Logger LOG = LoggerFactory.getLogger(this.getClass()); 029 030 private static SRUCQLQueryServiceImpl srucqlQueryService = null; 031 032 private SRUCQLQueryServiceImpl() { 033 } 034 035 public static SRUCQLQueryServiceImpl getInstance() { 036 if (srucqlQueryService == null) 037 srucqlQueryService = new SRUCQLQueryServiceImpl(); 038 return srucqlQueryService; 039 } 040 041 /** 042 * @param solrQuery 043 * @return return list of bib id values 044 * @throws Exception 045 */ 046 @Override 047 public List<OleDocument> queryForBibDocs(Map reqParamMap, String solrQuery) throws Exception { 048 LOG.info("Inside queryForBibDocs method"); 049 List<OleDocument> oleDocuments; 050 List<Map<String, Object>> solrHits; 051 solrQuery = getSolrReqQuery(reqParamMap, solrQuery); 052 solrHits = getSolrHitsForQuery(solrQuery, reqParamMap); 053 oleDocuments = buildOleDocuments(solrHits); 054 return oleDocuments; 055 056 } 057 058 059 /** 060 * @param term 061 * @param relation 062 * @param index 063 * @param solrQueryFlag 064 * @return solr query 065 * @throws Exception 066 */ 067 @Override 068 public String getQuery(String term, String relation, String index, boolean solrQueryFlag) throws Exception { 069 070 if (term != null) { 071 if (term.contains(":")) { 072 solrQueryFlag = false; 073 return null; 074 } 075 } 076 077 if (index.contains(DC) || (index.contains(OLE)) || (index.contains(BATH)) || (index.contains(REC))) { 078 if(index.contains(REC_ID) || (index.contains(OLE_ID)) || (index.contains(BATH_ID)) || (index.contains(DC_ID))){ 079 index = index.replaceAll(REC_ID,LOCAL_Id); 080 index = index.replaceAll(OLE_ID,LOCAL_Id); 081 index = index.replaceAll(BATH_ID,LOCAL_Id); 082 index = index.replaceAll(DC_ID,LOCAL_Id); 083 } 084 else{ 085 index = index.replaceAll(REC,""); 086 index = index.replaceAll(DC, ""); 087 index = index.replaceAll(OLE,""); 088 index = index.replaceAll(BATH,""); 089 } 090 } 091 092 if(SRU_QUERY_ADJ_RELATION.equals(relation) ) { 093 StringBuffer query = new StringBuffer(""); 094 String[] terms = term.split(" "); 095 query.append(getIndex(index) + "(" + "\""); 096 for (int i = 0; i < terms.length ; i++){ 097 if(i == terms.length -1) { 098 query.append(terms[i].toLowerCase()); 099 } 100 else{ 101 query.append(terms[i].toLowerCase() + "+"); 102 } 103 } 104 query.append("\"" + "))"); 105 return query.toString(); 106 } 107 108 if(SRU_QUERY_EQUALS_RELATION.equals(relation)) { 109 StringBuffer query = new StringBuffer(""); 110 String[] terms = term.split(" "); 111 query.append(getExactIndex(index) + "(" + "\""); 112 for (int i = 0; i < terms.length ; i++){ 113 if(i == terms.length -1) { 114 query.append(terms[i].toLowerCase()); 115 } 116 else{ 117 query.append(terms[i].toLowerCase() + "+"); 118 } 119 } 120 query.append("\"" + "))"); 121 return query.toString(); 122 } 123 124/* if ( SRU_QUERY_SRC_RELATION.equals(relation)) { 125 return "(all_text:(" + term + "))"; 126 }*/ 127 if (SRU_QUERY_ALL_RELATION.equals(relation)) { 128 StringBuffer query = new StringBuffer(""); 129 String[] terms = term.split(" "); 130 for (int i = 0; i < terms.length - 1; i++) 131 query.append(getIndex(index) + "(" + terms[i].toLowerCase() + ")) AND "); 132 query.append(getIndex(index) + "(" + terms[terms.length - 1].toLowerCase() + "))"); 133 return query.toString(); 134 } 135 if (SRU_QUERY_EXACT_RELATION.equals(relation)) { 136 return getExactIndex(index) + "(\"" + term + "\"))"; 137 } 138 if (SRU_QUERY_WITHIN_RELATION.equals(relation)) { 139 return getExactIndex(index) +getWithinQuery(term); 140 } 141 if (SRU_QUERY_ANY_RELATION.equals(relation)) { 142 StringBuffer query = new StringBuffer(""); 143 String[] terms = term.split(" "); 144 for (int i = 0; i < terms.length - 1; i++) 145 query.append(getIndex(index) + "(" + terms[i].toLowerCase() + ")) OR "); 146 query.append(getIndex(index) + "(" + terms[terms.length - 1].toLowerCase() + "))"); 147 return query.toString(); 148 } 149 if (relation.contains(SRU_QUERY_LESSERTHAN_RELATION)) { 150 StringBuffer query = new StringBuffer(""); 151 if (SRU_QUERY_LESSERTHAN_EQUAL_RELATION.equals(relation)) 152 query.append(getIndex(index) + "[0 TO " + term + "])"); 153 else { 154 int pubDate = Integer.parseInt(term) - 1; 155 query.append(getIndex(index) + "[0 TO " + pubDate + "])"); 156 } 157 return query.toString(); 158 } 159 160 if (relation.contains(SRU_QUERY_GREATERTHAN_RELATION)) { 161 StringBuffer query = new StringBuffer(""); 162 if (SRU_QUERY_GREATERTHAN_EQUAL_RELATION.equals(relation)) 163 query.append(getIndex(index) + "[" + term + " TO NOW])"); 164 else { 165 int pubDate = Integer.parseInt(term) + 1; 166 query.append(getIndex(index) + "[" + pubDate + " TO NOW])"); 167 } 168 return query.toString(); 169 } 170 171 if (SRU_QUERY_TITLE.equalsIgnoreCase(index)) 172 return getIndex(index) + "(" + term.toLowerCase() + "))"; 173 if (SRU_QUERY_AUTHOR.equalsIgnoreCase(index) || SRU_QUERY_CREATOR.equals(index)) 174 return getIndex(index) + "(" + term.toLowerCase() + "))"; 175 if (SRU_QUERY_PUBLICATION_DATE.equalsIgnoreCase(index) || SRU_QUERY_DATE.equalsIgnoreCase(index)) 176 return getIndex(index) + "(" + term.toLowerCase() + "))"; 177 if (SRU_QUERY_ISBN.equalsIgnoreCase(index)) 178 return getIndex(index) + "(" + term.toLowerCase() + "))"; 179 if (SRU_QUERY_PUBLISHER.equalsIgnoreCase(index)) 180 return getIndex(index) + "(" + term.toLowerCase() + "))"; 181 if (SRU_QUERY_ISSN.equalsIgnoreCase(index)) 182 return getIndex(index) + "(" + term.toLowerCase() + "))"; 183 if (SRU_QUERY_LOCAL_ID.equalsIgnoreCase(index)) 184 return getIndex(index) + "(" + term.toLowerCase() + "))"; 185 if (SRU_QUERY_OCLC.equalsIgnoreCase(index)) 186 return getIndex(index) + "(" + term.toLowerCase() + "))"; 187 if (SRU_QUERY_SUBJECT.equalsIgnoreCase(index)) 188 return getIndex(index) + "(" + term.toLowerCase() + "))"; 189 if(SRU_QUERY_SERVER_CHOICE.equalsIgnoreCase(index)) 190 return getIndex(index) + "(" + term.toLowerCase() + "))"; 191 if(SRU_QUERY_CQL_KEYWORDS.equalsIgnoreCase(index)) 192 return getIndex(index) + "(" + term.toLowerCase() + "))"; 193 return ""; 194 195 } 196 197 /** 198 * @param index 199 * @return query fields string 200 */ 201 public String getIndex(String index) { 202 203 if (SRU_QUERY_TITLE.equalsIgnoreCase(index)) 204 return "(Title_search:"; 205 if (SRU_QUERY_AUTHOR.equalsIgnoreCase(index) || SRU_QUERY_CREATOR.equals(index)) 206 return "(Author_search:"; 207 if (SRU_QUERY_PUBLICATION_DATE.equalsIgnoreCase(index) || SRU_QUERY_DATE.equalsIgnoreCase(index)) 208 return "(PublicationDate_search:"; 209 if (SRU_QUERY_ISBN.equalsIgnoreCase(index)) 210 return "(ISBN_search:"; 211 if (SRU_QUERY_PUBLISHER.equalsIgnoreCase(index)) 212 return "(Publisher_search:"; 213 if (SRU_QUERY_ISSN.equalsIgnoreCase(index)) 214 return "(ISSN_search:"; 215 if (SRU_QUERY_LOCAL_ID.equalsIgnoreCase(index)) 216 return "(LocalId_search:"; 217 if (SRU_QUERY_OCLC.equalsIgnoreCase(index)) 218 return "(035a:"; 219 if (SRU_QUERY_SUBJECT.equalsIgnoreCase(index)) 220 return "(Subject_search:"; 221 if(SRU_QUERY_SERVER_CHOICE.equalsIgnoreCase(index)) 222 return "(all_text:"; 223 if(SRU_QUERY_CQL_KEYWORDS.equalsIgnoreCase(index)) 224 return "(all_text:"; 225 return ""; 226 } 227 228 /** 229 * @param index 230 * @return query fields string 231 */ 232 public String getExactIndex(String index) { 233 234 if (SRU_QUERY_TITLE.equalsIgnoreCase(index)) 235 return "(Title_display:"; 236 if (SRU_QUERY_AUTHOR.equalsIgnoreCase(index) || SRU_QUERY_CREATOR.equals(index)) 237 return "(Author_display:"; 238 if (SRU_QUERY_PUBLICATION_DATE.equalsIgnoreCase(index) || SRU_QUERY_DATE.equalsIgnoreCase(index)) 239 return "(PublicationDate_display:"; 240 if (SRU_QUERY_ISBN.equalsIgnoreCase(index)) 241 return "(ISBN_display:"; 242 if (SRU_QUERY_PUBLISHER.equalsIgnoreCase(index)) 243 return "(Publisher_display:"; 244 if (SRU_QUERY_ISSN.equalsIgnoreCase(index)) 245 return "(ISSN_display:"; 246 if (SRU_QUERY_LOCAL_ID.equalsIgnoreCase(index)) 247 return "(LocalId_display:"; 248 if (SRU_QUERY_OCLC.equalsIgnoreCase(index)) 249 return "(035a:"; 250 if (SRU_QUERY_SUBJECT.equalsIgnoreCase(index)) 251 return "(Subject_display:"; 252 return ""; 253 } 254 255 /** 256 * @param sortKey 257 * @return 258 */ 259 public String getSortKeyValue(String sortKey) { 260 261 String sortKeys[] = sortKey.split(","); 262 if (SRU_QUERY_TITLE.equalsIgnoreCase(sortKeys[0])) 263 return "Title_sort asc"; 264 if (SRU_QUERY_AUTHOR.equalsIgnoreCase(sortKeys[0])) 265 return "Author_sort asc"; 266 if (SRU_QUERY_PUBLICATION_DATE.equalsIgnoreCase(sortKeys[0])) 267 return "PublicationDate_sort asc"; 268 if (SRU_QUERY_ISBN.equalsIgnoreCase(sortKeys[0])) 269 return "ISBN_sort asc"; 270 if (SRU_QUERY_PUBLISHER.equalsIgnoreCase(sortKeys[0])) 271 return "Publisher_sort asc"; 272 273 return ""; 274 } 275 276 /** 277 * @param hitsOnPage 278 * @return List of OleDocuments 279 */ 280 public List<OleDocument> buildOleDocuments(List<Map<String, Object>> hitsOnPage) { 281 List<OleDocument> oleDocuments = new ArrayList<OleDocument>(); 282 for (Map<String, Object> hitsOnPageItr : hitsOnPage) { 283 WorkBibDocument workBibDocument = new WorkBibDocument(); 284 Map map = hitsOnPageItr; 285 Set keys = map.keySet(); 286 for (Object key : keys) { 287 if ("id".equalsIgnoreCase(key.toString())) { 288 workBibDocument.setId((String) map.get(key)); 289 } 290 if ("instanceIdentifier".equalsIgnoreCase(key.toString())) { 291 Object object = map.get(key); 292 List<WorkInstanceDocument> workInstanceDocuments = new ArrayList<WorkInstanceDocument>(); 293 List<WorkEInstanceDocument> workEInstanceDocuments = new ArrayList<WorkEInstanceDocument>(); 294 if (object instanceof String) { 295 String id = (String) object; 296 if(id.startsWith("wen")){ 297 WorkEInstanceDocument workEInstanceDocument = new WorkEInstanceDocument(); 298 workEInstanceDocument.setInstanceIdentifier(id); 299 workEInstanceDocuments.add(workEInstanceDocument); 300 }else{ 301 WorkInstanceDocument workInstanceDocument = new WorkInstanceDocument(); 302 workInstanceDocument.setInstanceIdentifier((String) object); 303 workInstanceDocuments.add(workInstanceDocument); 304 } 305 } else if (object instanceof List) { 306 List<String> instanceIds = (List<String>) object; 307 for (String id : instanceIds) { 308 if(id.startsWith("wen")){ 309 WorkEInstanceDocument workEInstanceDocument = new WorkEInstanceDocument(); 310 workEInstanceDocument.setInstanceIdentifier(id); 311 workEInstanceDocuments.add(workEInstanceDocument); 312 }else{ 313 WorkInstanceDocument workInstanceDocument = new WorkInstanceDocument(); 314 workInstanceDocument.setInstanceIdentifier(id); 315 workInstanceDocuments.add(workInstanceDocument); 316 } 317 } 318 } 319 workBibDocument.setWorkInstanceDocumentList(workInstanceDocuments); 320 workBibDocument.setWorkEInstanceDocumentList(workEInstanceDocuments); 321 } 322 } 323 oleDocuments.add(workBibDocument); 324 } 325 return oleDocuments; 326 } 327 328 /** 329 * @param inputQuery 330 * @return hitsOnPage 331 * @throws Exception Usage: Gets Solr response for input query and builds List of Maps holding Solr Doc Data 332 */ 333 public List<Map<String, Object>> getSolrHitsForQuery(String inputQuery, Map reqParamMap) throws Exception { 334 SolrServer server; 335 List<Map<String, Object>> hitsOnPage = new ArrayList<Map<String, Object>>(); 336 server = SolrServerManager.getInstance().getSolrServer(); 337 SolrQuery solrQuery = new SolrQuery(); 338 solrQuery.setQuery(inputQuery); 339 solrQuery.setIncludeScore(true); 340 solrQuery.set("fl", "id,instanceIdentifier"); 341 solrQuery.set("start", reqParamMap.get(START_RECORD).toString()); 342 solrQuery.set("rows", reqParamMap.get(MAXIMUM_RECORDS).toString()); 343 solrQuery.set("sort", getSortKeyValue(reqParamMap.get(SORTKEYS).toString())); 344 QueryResponse queryResponse = server.query(solrQuery); 345 SolrDocumentList solrDocumentList = queryResponse.getResults(); 346 reqParamMap.put("numberOfRecords", queryResponse.getResults().getNumFound()); 347 for (SolrDocument solrDocument : solrDocumentList) { 348 hitsOnPage.add(solrDocument); 349 } 350 return hitsOnPage; 351 } 352 353 public String getSolrReqQuery(Map reqParamMap, String solrQuery) { 354 StringBuffer query = new StringBuffer(""); 355 String recordSchema= (String)reqParamMap.get(RECORD_SCHEMA); 356 if (recordSchema != null) { 357 if (recordSchema.equalsIgnoreCase("OPAC")) { 358 query.append("(DocFormat:marc AND staffOnlyFlag:false) AND DocType:bibliographic AND "); 359 } else { 360 query.append("(DocFormat:" + reqParamMap.get(RECORD_SCHEMA).toString() + "AND staffOnlyFlag:false) AND DocType:bibliographic AND "); 361 } 362 } 363 query.append(solrQuery); 364 LOG.info("solr Query SRUCQLQueryServiceImpl"+query); 365 query = new StringBuffer(query.toString().replace("+", " ")); 366 return query.toString(); 367 } 368 public String getWithinQuery(String term){ 369 String range[]=term.split("[' ']"); 370 return "[" + range[0] +" TO "+range[1] + "])"; 371 } 372}