View Javadoc
1   package org.kuali.ole.docstore.discovery.service;
2   
3   import org.apache.solr.client.solrj.SolrQuery;
4   import org.apache.solr.client.solrj.SolrServer;
5   import org.apache.solr.client.solrj.response.QueryResponse;
6   import org.apache.solr.common.SolrDocument;
7   import org.apache.solr.common.SolrDocumentList;
8   import org.kuali.ole.docstore.model.bo.OleDocument;
9   import org.kuali.ole.docstore.model.bo.WorkBibDocument;
10  import org.kuali.ole.docstore.model.bo.WorkEInstanceDocument;
11  import org.kuali.ole.docstore.model.bo.WorkInstanceDocument;
12  import org.slf4j.Logger;
13  import org.slf4j.LoggerFactory;
14  import java.util.ArrayList;
15  import java.util.List;
16  import java.util.Map;
17  import java.util.Set;
18  
19  /**
20   * Created with IntelliJ IDEA.
21   * User: ?
22   * Date: 8/6/12
23   * Time: 11:42 AM
24   * To change this template use File | Settings | File Templates.
25   */
26  public class SRUCQLQueryServiceImpl implements SRUCQLQueryService {
27  
28      private Logger LOG = LoggerFactory.getLogger(this.getClass());
29  
30      private static SRUCQLQueryServiceImpl srucqlQueryService = null;
31  
32      private SRUCQLQueryServiceImpl() {
33      }
34  
35      public static SRUCQLQueryServiceImpl getInstance() {
36          if (srucqlQueryService == null)
37              srucqlQueryService = new SRUCQLQueryServiceImpl();
38          return srucqlQueryService;
39      }
40  
41      /**
42       * @param solrQuery
43       * @return return list of bib id values
44       * @throws Exception
45       */
46      @Override
47      public List<OleDocument> queryForBibDocs(Map reqParamMap, String solrQuery) throws Exception {
48          LOG.info("Inside queryForBibDocs method");
49          List<OleDocument> oleDocuments;
50          List<Map<String, Object>> solrHits;
51          solrQuery = getSolrReqQuery(reqParamMap, solrQuery);
52          solrHits = getSolrHitsForQuery(solrQuery, reqParamMap);
53          oleDocuments = buildOleDocuments(solrHits);
54          return oleDocuments;
55  
56      }
57  
58  
59      /**
60       * @param term
61       * @param relation
62       * @param index
63       * @param solrQueryFlag
64       * @return solr query
65       * @throws Exception
66       */
67      @Override
68      public String getQuery(String term, String relation, String index, boolean solrQueryFlag) throws Exception {
69  
70          if (term != null) {
71              if (term.contains(":")) {
72                  solrQueryFlag = false;
73                  return null;
74              }
75          }
76  
77          if (index.contains(DC) || (index.contains(OLE)) || (index.contains(BATH)) || (index.contains(REC))) {
78              if(index.contains(REC_ID) || (index.contains(OLE_ID)) || (index.contains(BATH_ID)) || (index.contains(DC_ID))){
79                  index = index.replaceAll(REC_ID,LOCAL_Id);
80                  index = index.replaceAll(OLE_ID,LOCAL_Id);
81                  index = index.replaceAll(BATH_ID,LOCAL_Id);
82                  index = index.replaceAll(DC_ID,LOCAL_Id);
83              }
84              else{
85              index = index.replaceAll(REC,"");
86              index = index.replaceAll(DC, "");
87              index = index.replaceAll(OLE,"");
88              index = index.replaceAll(BATH,"");
89              }
90             }
91  
92          if(SRU_QUERY_ADJ_RELATION.equals(relation) ) {
93              StringBuffer query = new StringBuffer("");
94              String[] terms = term.split(" ");
95              query.append(getIndex(index) + "(" + "\"");
96              for (int i = 0; i < terms.length ; i++){
97                  if(i == terms.length -1) {
98                      query.append(terms[i].toLowerCase());
99                  }
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 }