View Javadoc
1   package org.kuali.ole.docstore.engine.service.search;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.apache.solr.client.solrj.SolrRequest;
5   import org.apache.solr.client.solrj.SolrServer;
6   import org.apache.solr.client.solrj.SolrServerException;
7   import org.apache.solr.client.solrj.response.*;
8   import org.apache.solr.common.SolrDocument;
9   import org.apache.solr.common.SolrDocumentList;
10  import org.kuali.ole.DocumentUniqueIDPrefix;
11  import org.kuali.ole.docstore.common.document.*;
12  import org.kuali.ole.docstore.common.exception.DocstoreIndexException;
13  import org.kuali.ole.docstore.common.search.*;
14  import org.kuali.ole.docstore.common.search.FacetResultField;
15  import org.kuali.ole.docstore.discovery.service.SolrServerManager;
16  import org.kuali.ole.docstore.engine.service.index.solr.BibConstants;
17  import org.kuali.ole.docstore.model.enums.DocType;
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  import org.apache.solr.client.solrj.SolrQuery;
21  import org.springframework.util.CollectionUtils;
22  
23  import java.text.CharacterIterator;
24  import java.text.StringCharacterIterator;
25  import java.util.*;
26  
27  /**
28   * Created with IntelliJ IDEA.
29   * User: sambasivam
30   * Date: 12/13/13
31   * Time: 6:42 PM
32   * To change this template use File | Settings | File Templates.
33   */
34  public class DocstoreSolrSearchService implements DocstoreSearchService {
35  
36      private static final Logger LOG = LoggerFactory.getLogger(DocstoreSolrSearchService.class);
37  
38  
39      private static Map<String, String> searchResultFieldsMap = new HashMap<>();
40  
41      private static Map<String, String> searchFieldsMap = new HashMap<>();
42      private static Map<String, String> joinQueryMap = new HashMap<>();
43      private static final String BIB_HOLDINGS = "bibliographicholdings";
44      private static final String BIB_EHOLDINGS = "bibliographiceHoldings";
45      private static final String BIB_ITEM="bibliographicitem";
46      private static final String HOLDINGS_BIB = "holdingsbibliographic";
47      private static final String EHOLDINGS_BIB = "eHoldingsbibliographic";
48      private static final String HOLDINGS_ITEM = "holdingsitem";
49      private static final String ITEM_HOLDINGS = "itemholdings";
50      private static final String ITEM_BIB = "itembibliographic";
51      static {
52          searchFieldsMap.put(Bib.ID, "id");
53          searchFieldsMap.put(Bib.AUTHOR, "Author_search");
54          searchFieldsMap.put(Bib.TITLE, "Title_search");
55          searchFieldsMap.put(Bib.PUBLICATIONDATE, "PublicationDate_search");
56          searchFieldsMap.put(Bib.PUBLISHER, "Publisher_search");
57          searchFieldsMap.put(Bib.ISBN, "ISBN_search");
58          searchFieldsMap.put(Bib.ISSN, "ISSN_search");
59          searchFieldsMap.put(Bib.SUBJECT, "Subject_search");
60          searchFieldsMap.put(Bib.EDITION, "Edition_search");
61          searchFieldsMap.put(Bib.DESCRIPTION, "Description_search");
62          searchFieldsMap.put(Bib.FORMAT, "Format_search");
63          searchFieldsMap.put(Bib.LANGUAGE, "Language_search");
64          searchFieldsMap.put(Bib.BIBIDENTIFIER, "bibIdentifier");
65          searchFieldsMap.put(Holdings.HOLDINGSIDENTIFIER, "holdingsIdentifier");
66          searchFieldsMap.put(Holdings.LOCATION_NAME, "Location_search");
67          searchFieldsMap.put(Holdings.LOCATION_LEVEL1, "Location_search");
68          searchFieldsMap.put(Holdings.LOCATION_LEVEL2, "Location_search");
69          searchFieldsMap.put(Holdings.LOCATION_LEVEL3, "Location_search");
70          searchFieldsMap.put(Holdings.LOCATION_LEVEL4, "Location_search");
71          searchFieldsMap.put(Holdings.LOCATION_LEVEL5, "Location_search");
72          searchFieldsMap.put(Holdings.CALL_NUMBER, "CallNumber_search");
73          searchFieldsMap.put(Holdings.CALLNUMBER_PREFIX, "CallNumberPrefix_search");
74          searchFieldsMap.put(Holdings.CALLNUMBER_TYPE, "CallNumberType_search");
75          searchFieldsMap.put(Holdings.COPY_NUMBER, "CopyNumber_search");
76          searchFieldsMap.put(Item.ITEMIDENTIFIER, "ItemIdentifier_search");
77          searchFieldsMap.put(Item.SHELVING_ORDER, "ShelvingOrder_search");
78          searchFieldsMap.put(Item.ITEM_BARCODE, "ItemBarcode_search");
79          searchFieldsMap.put(Item.ENUMERATION, "Enumeration_search");
80          searchFieldsMap.put(Item.CHRONOLOGY, "Chronology_search");
81          searchFieldsMap.put(Item.ITEM_TYPE, "ItemTypeCodeValue_search");
82          searchFieldsMap.put(Item.VOLUME_NUMBER, "VolumeNumber_search");
83          searchFieldsMap.put(Item.ITEM_STATUS, "ItemStatus_search");
84          searchFieldsMap.put(Item.ITEMIDENTIFIER, "ItemIdentifier_search");
85          searchFieldsMap.put(Item.DONOR_CODE, "DonorCode_search");
86          searchFieldsMap.put(Item.DONOR_NOTE, "DonorNote_display");
87          searchFieldsMap.put(Item.DONOR_PUBLIC, "DonorPublic_display");
88          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER, "HoldingsCallNumber_search");
89          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_PREFIX, "CallNumberPrefix_search");
90          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_TYPE, "CallNumberType_search");
91          searchFieldsMap.put(Item.HOLDINGS_COPY_NUMBER, "HoldingsCopyNumber_search");
92          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL1, "HoldingsLocation_search");
93          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL2, "HoldingsLocation_search");
94          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL3, "HoldingsLocation_search");
95          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL4, "HoldingsLocation_search");
96          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL5, "HoldingsLocation_search");
97          searchFieldsMap.put(Item.VENDOR_LINE_ITEM_IDENTIFIER, "VendorLineItemIdentifier_search");
98          searchFieldsMap.put(EHoldings.ACCESS_STATUS, "AccessStatus_search");
99          searchFieldsMap.put(EHoldings.URL, "URL_search");
100         searchFieldsMap.put(EHoldings.PERSISTENT_LINK, "Persist_Link_search");
101         searchFieldsMap.put(EHoldings.LINK_TEXT, "Link_Text_search");
102         searchFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "Public_Note_display");
103         searchFieldsMap.put(EHoldings.COVERAGE_START_DATE, "CoverageDate_display");
104         searchFieldsMap.put(EHoldings.COVERAGE_END_DATE, "CoverageDate_display");
105         searchFieldsMap.put(EHoldings.STATISTICAL_CODE, "StatisticalSearchingCodeValue_display");
106         searchFieldsMap.put(EHoldings.PLATFORM, "Platform_display");
107 
108         searchResultFieldsMap.put(Bib.ID, "id");
109         searchResultFieldsMap.put(Bib.AUTHOR, "Author_display");
110         searchResultFieldsMap.put(Bib.TITLE, "Title_display");
111         searchResultFieldsMap.put(Bib.PUBLICATIONDATE, "PublicationDate_display");
112         searchResultFieldsMap.put(Bib.PUBLISHER, "Publisher_display");
113         searchResultFieldsMap.put(Bib.ISBN, "ISBN_display");
114         searchResultFieldsMap.put(Bib.ISSN, "ISSN_display");
115         searchResultFieldsMap.put(Bib.SUBJECT, "Subject_display");
116         searchResultFieldsMap.put(Bib.EDITION, "Edition_display");
117         searchResultFieldsMap.put(Bib.DESCRIPTION, "Description_display");
118         searchResultFieldsMap.put(Bib.FORMAT, "Format_display");
119         searchResultFieldsMap.put(Bib.LANGUAGE, "Language_display");
120         searchResultFieldsMap.put(Bib.BIBIDENTIFIER, "bibIdentifier");
121         searchResultFieldsMap.put(Holdings.HOLDINGSIDENTIFIER, "holdingsIdentifier");
122         searchResultFieldsMap.put(Holdings.LOCATION_NAME, "Location_display");
123         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL1, "Location_display");
124         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL2, "Location_display");
125         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL3, "Location_display");
126         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL4, "Location_display");
127         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL5, "Location_display");
128         searchResultFieldsMap.put(Holdings.CALL_NUMBER, "CallNumber_display");
129         searchResultFieldsMap.put(Holdings.CALLNUMBER_PREFIX, "CallNumberPrefix_display");
130         searchResultFieldsMap.put(Holdings.CALLNUMBER_TYPE, "CallNumberType_display");
131         searchResultFieldsMap.put(Holdings.COPY_NUMBER, "CopyNumber_display");
132         searchResultFieldsMap.put(Item.ITEMIDENTIFIER, "itemIdentifier");
133         searchResultFieldsMap.put(Item.SHELVING_ORDER, "ShelvingOrder_display");
134         searchResultFieldsMap.put(Item.ITEM_BARCODE, "ItemBarcode_display");
135         searchResultFieldsMap.put(Item.ENUMERATION, "Enumeration_display");
136         searchResultFieldsMap.put(Item.CHRONOLOGY, "Chronology_display");
137         searchResultFieldsMap.put(Item.ITEM_TYPE, "ItemTypeCodeValue_display");
138         searchResultFieldsMap.put(Item.VOLUME_NUMBER, "VolumeNumber_display");
139         searchResultFieldsMap.put(Item.ITEM_STATUS, "ItemStatus_display");
140         searchResultFieldsMap.put(Item.DONOR_CODE, "DonorCode_display");
141         searchResultFieldsMap.put(Item.DONOR_NOTE, "DonorNote_display");
142         searchResultFieldsMap.put(Item.DONOR_PUBLIC, "DonorPublic_display");
143         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER, "HoldingsCallNumber_display");
144         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_PREFIX, "CallNumberPrefix_display");
145         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_TYPE, "CallNumberType_display");
146         searchResultFieldsMap.put(Item.HOLDINGS_COPY_NUMBER, "HoldingsCopyNumber_display");
147         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL1, "HoldingsLocation_display");
148         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL2, "HoldingsLocation_display");
149         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL3, "HoldingsLocation_display");
150         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL4, "HoldingsLocation_display");
151         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL5, "HoldingsLocation_display");
152         searchResultFieldsMap.put(Item.VENDOR_LINE_ITEM_IDENTIFIER, "VendorLineItemIdentifier_display");
153         searchResultFieldsMap.put(EHoldings.ACCESS_STATUS, "AccessStatus_display");
154         searchResultFieldsMap.put(EHoldings.URL, "URL_display");
155         searchResultFieldsMap.put(EHoldings.PERSISTENT_LINK, "Persist_Link_display");
156         searchResultFieldsMap.put(EHoldings.LINK_TEXT, "Link_Text_display");
157         searchResultFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "Public_Note_display");
158         searchResultFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "CoverageDate_display");
159         searchResultFieldsMap.put(EHoldings.STATISTICAL_CODE, "StatisticalSearchingCodeValue_display");
160         searchResultFieldsMap.put(EHoldings.PLATFORM, "Platform_display");
161         searchResultFieldsMap.put(Bib.BIBIDENTIFIER, "bibIdentifier");
162         searchResultFieldsMap.put(Holdings.HOLDINGSIDENTIFIER, "holdingsIdentifier");
163         searchResultFieldsMap.put(Item.ITEMIDENTIFIER, "itemIdentifier");
164 
165 
166         joinQueryMap.put(BIB_HOLDINGS, "{!join from=id to=holdingsIdentifier}");
167         joinQueryMap.put(HOLDINGS_BIB, "{!join from=id to=bibIdentifier}");
168         joinQueryMap.put(BIB_EHOLDINGS, "{!join from=id to=holdingsIdentifier}");
169         joinQueryMap.put(EHOLDINGS_BIB, "{!join from=id to=bibIdentifier}");
170         joinQueryMap.put(HOLDINGS_ITEM, "{!join from=id to=itemIdentifier}");
171         joinQueryMap.put(ITEM_BIB, "{!join from=id to=bibIdentifier}");
172         joinQueryMap.put(ITEM_HOLDINGS, "{!join from=id to=holdingsIdentifier}");
173         joinQueryMap.put(BIB_ITEM, "{!join from=id to=itemIdentifier}");
174     }
175 
176     @Override
177     public SearchResponse search(SearchParams searchParams) {
178         try {
179             SolrQuery solrQuery = new SolrQuery();
180             SolrServer server = SolrServerManager.getInstance().getSolrServer();
181             buildQueryWithSearchConditions(searchParams,solrQuery);
182             if (!CollectionUtils.isEmpty(searchParams.getSortConditions())) {
183                 buildQueryWithSortConditions(solrQuery, searchParams.getSortConditions());
184             }
185             if (searchParams.getPageSize() != 0) {
186                 solrQuery.setRows(searchParams.getPageSize());
187             }
188             solrQuery.setStart(searchParams.getStartIndex());
189             if (!CollectionUtils.isEmpty(searchParams.getSearchResultFields())) {
190                 solrQuery.setFields(buildQueryWithResultFieldsLists(searchParams));
191             }
192             if (!CollectionUtils.isEmpty(searchParams.getFacetFields())) {
193                 for(String facetField : searchParams.getFacetFields()) {
194                     solrQuery.addFacetField(facetField);
195                 }
196                 solrQuery.setFacet(true);
197                 if(StringUtils.isNotEmpty(searchParams.getFacetPrefix())) {
198                     if(!searchParams.getFacetPrefix().equalsIgnoreCase("all")) {
199                         solrQuery.setFacetPrefix(searchParams.getFacetPrefix().toLowerCase());
200                     }
201                 }
202 //                else {
203                     solrQuery.setFacetLimit(searchParams.getFacetLimit());
204 //                }
205                 solrQuery.setFacetMinCount(1);
206                 solrQuery.setFacetSort(searchParams.getFacetSort());
207                 solrQuery.set("facet.offset", searchParams.getFacetOffset());
208             }
209 
210             if (!CollectionUtils.isEmpty(searchParams.getFacetConditions())) {
211                buildQueryWithFacetConditions(solrQuery, searchParams.getFacetConditions());
212             }
213             LOG.info("Executing solr query :" +solrQuery.toString());
214             QueryResponse response = server.query(solrQuery, SolrRequest.METHOD.POST);
215             return buildSearchResponse(response, searchParams);
216         } catch (SolrServerException ex) {
217             LOG.info("Exception :", ex);
218             throw new DocstoreIndexException(ex.getMessage());
219         }
220     }
221 
222     private void buildQueryWithFacetConditions(SolrQuery solrQuery, List<FacetCondition> facetConditions) {
223 
224         StringBuffer facetTerms = new StringBuffer();
225         StringBuffer filterQuery = new StringBuffer();
226         int facetConditionsSize = facetConditions.size();
227         for (int i=0; i < facetConditionsSize; i++) {
228             FacetCondition facetCondition = facetConditions.get(i);
229             if(StringUtils.isNotEmpty(facetCondition.getFieldValue())) {
230                 facetTerms.append(facetCondition.getFieldValue());
231                 if(i != (facetConditionsSize-1)) {
232                     facetTerms.append("|");
233                 }
234             }
235             if(StringUtils.isNotEmpty(facetCondition.getFieldValue())) {
236                 filterQuery.append(facetCondition.getFieldName());
237                 filterQuery.append(":");
238                 filterQuery.append("\"" + facetCondition.getFieldValue() + "\"");
239 
240                 if(i != (facetConditionsSize-1)) {
241                     filterQuery.append(" AND ");
242                 }
243             }
244         }
245 
246         solrQuery.setTermsRegex(facetTerms.toString());
247         solrQuery.setFilterQueries(filterQuery.toString());
248     }
249 
250 
251     private SearchResponse buildSearchResponse(QueryResponse response, SearchParams searchParams) {
252         SolrDocumentList results = response.getResults();
253         List<org.apache.solr.client.solrj.response.FacetField> facetFields = response.getFacetFields();
254         String searchConditionDocType = searchParams.getDocType();
255         SearchResponse searchResponse = new SearchResponse();
256         List<SearchResult> searchResults = new ArrayList<>();
257         if (StringUtils.isEmpty(searchConditionDocType) && !CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
258             for(SearchCondition searchCondition:searchParams.getSearchConditions()){
259                 if(searchCondition.getSearchField()!=null){
260                     searchConditionDocType = searchCondition.getSearchField().getDocType();
261                     break;
262                 }
263             }
264         }
265         List<SearchResultField> searchResultFields = new ArrayList<SearchResultField>();
266         if (CollectionUtils.isEmpty(searchParams.getSearchResultFields())) {
267             searchResultFields = getDefaultSearchResultFields(searchParams);
268         } else {
269             searchResultFields = searchParams.getSearchResultFields();
270         }
271         for (SolrDocument solrDocument : results) {
272             SolrDocument bibSolrDocument = null;
273             //SolrDocument holdingsSolrDocument = null;
274             //SolrDocument itemSolrDocument = null;
275             SearchResult searchResult = new SearchResult();
276             List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
277             for (SearchResultField searchResultField : searchResultFields) {
278                 SearchResultField newSearchResultField = new SearchResultField();
279                 if (StringUtils.isBlank(searchConditionDocType) || searchResultField.getDocType().equalsIgnoreCase(searchConditionDocType)) {
280                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
281                     if (fieldValue.equalsIgnoreCase("id") || fieldValue.equalsIgnoreCase("bibIdentifier")
282                             || fieldValue.equalsIgnoreCase("holdingsIdentifier")
283                             || fieldValue.equalsIgnoreCase("itemIdentifier")
284                             || fieldValue.equalsIgnoreCase("ItemIdentifier_display")
285                             || fieldValue.equalsIgnoreCase("DonorCode_search")
286                             || fieldValue.equalsIgnoreCase("DonorCode_display")
287                             || fieldValue.equalsIgnoreCase("ISBN_search")
288                             || fieldValue.equalsIgnoreCase("ISBN_display")
289                             || fieldValue.equalsIgnoreCase("ISSN_search")
290                             || fieldValue.equalsIgnoreCase("ISSN_display")) {
291                         newSearchResultFields.addAll(buildSearchResultsForIds(solrDocument, searchResultField));
292                         continue;
293                     }
294                     if(fieldValue.equalsIgnoreCase("Title_sort")){
295                         fieldValue="Title_display";
296                     }
297                     String resultFieldValue = getSolrFieldValue(solrDocument, fieldValue);
298                     if (StringUtils.isNotBlank(resultFieldValue)) {
299                         newSearchResultField.setFieldValue(resultFieldValue);
300                     }
301                 } else {
302                     if (searchResultField.getDocType().equalsIgnoreCase(HOLDINGS)) {
303                         if (searchConditionDocType.equalsIgnoreCase(ITEM) || searchConditionDocType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
304                             newSearchResultFields.addAll(buildHoldingsSearchResults(solrDocument, searchResultField));
305                             continue;
306                         }
307                     } else if (searchResultField.getDocType().equalsIgnoreCase(BIBLIOGRAPHIC)) {
308                         if (searchConditionDocType.equalsIgnoreCase(ITEM) || searchConditionDocType.equalsIgnoreCase(HOLDINGS) || searchConditionDocType.equalsIgnoreCase(EHOLDINGS) ) {
309                              newSearchResultFields.addAll(buildBibSearchResults(solrDocument, searchResultField));
310                             continue;
311                         }
312                     } else if (searchResultField.getDocType().equalsIgnoreCase(ITEM)) {
313                         if (searchConditionDocType.equalsIgnoreCase(HOLDINGS)) {
314                             newSearchResultFields.addAll(buildItemSearchResultsForHoldings(solrDocument, searchResultField));
315                             continue;
316                         } else if (searchConditionDocType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
317                             newSearchResultFields.addAll(buildItemSearchResultsForBib(solrDocument, searchResultField));
318                             continue;
319                         }
320                     } else if (searchConditionDocType.equalsIgnoreCase(EHOLDINGS)) {
321                         if (bibSolrDocument == null) {
322                             bibSolrDocument = getBibRecord((String) solrDocument.getFieldValue("bibIdentifier"));
323                         }
324                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
325                         String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
326                         if (StringUtils.isNotBlank(resultFieldValue)) {
327                             newSearchResultField.setFieldValue(resultFieldValue);
328                         }
329                     }
330                 }
331                 newSearchResultField.setDocType(searchResultField.getDocType());
332                 newSearchResultField.setFieldName(searchResultField.getFieldName());
333                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
334                 newSearchResultFields.add(newSearchResultField);
335             }
336             searchResult.getSearchResultFields().addAll(newSearchResultFields);
337             searchResults.add(searchResult);
338         }
339         searchResponse.getSearchResults().addAll(searchResults);
340         searchResponse.setTotalRecordCount((int) results.getNumFound());
341         if (searchParams.getPageSize() == 0) {
342             searchResponse.setPageSize(results.size());
343         } else {
344             searchResponse.setPageSize(searchParams.getPageSize());
345         }
346         searchResponse.setStartIndex(searchParams.getStartIndex());
347         searchResponse.setEndIndex(searchParams.getStartIndex() + searchParams.getPageSize());
348         FacetResult facetResult = new FacetResult();
349         if (!CollectionUtils.isEmpty(facetFields)) {
350 
351             for (org.apache.solr.client.solrj.response.FacetField facetField : facetFields) {
352 
353 
354                 FacetResultField facetFieldResult = new FacetResultField();
355                 facetFieldResult.setFieldName(facetField.getName());
356 
357                 if(facetField.getValues() != null) {
358                     for (org.apache.solr.client.solrj.response.FacetField.Count count : facetField.getValues()) {
359                         String valCount = String.valueOf(count.getCount());
360                         if(!valCount.equalsIgnoreCase("0")) {
361 
362                             ValueCount valueCount = new ValueCount();
363                             String fullValue = count.getName();
364                             String value = "";
365                             if(fullValue.contains("/r/n!@#$")) {
366                                 int index = fullValue.indexOf("/r/n!@#$");
367                                 value = fullValue.substring(index + 8, fullValue.length());
368                             }
369                             else {
370                                 value = fullValue;
371                             }
372                             valueCount.setValue(value);
373                             valueCount.setFullValue(count.getName());
374                             valueCount.setCount(valCount);
375                             facetFieldResult.getValueCounts().add(valueCount);
376                         }
377                     }
378                 }
379 
380                 facetResult.getFacetResultFields().add(facetFieldResult);
381             }
382         }
383 
384         searchResponse.setFacetResult(facetResult);
385         searchResponse.setTime(response.getQTime());
386         return searchResponse;
387     }
388 
389     private List<SearchResultField> buildSearchResultsForIds(SolrDocument solrDocument, SearchResultField searchResultField) {
390         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
391         Object object = solrDocument.getFieldValue(searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName());
392         if (object instanceof String) {
393             SearchResultField newSearchResultField = new SearchResultField();
394             newSearchResultField.setDocType(searchResultField.getDocType());
395             newSearchResultField.setFieldName(searchResultField.getFieldName());
396             newSearchResultField.setFieldValue((String) object);
397             newSearchResultFields.add(newSearchResultField);
398         } else {
399             if (((List) object) != null) {
400                 for (Object identifier : (List) object) {
401                     SearchResultField newSearchResultField = new SearchResultField();
402                     newSearchResultField.setDocType(searchResultField.getDocType());
403                     newSearchResultField.setFieldName(searchResultField.getFieldName());
404                     newSearchResultField.setFieldValue((String) identifier);
405                     newSearchResultFields.add(newSearchResultField);
406                 }
407             }
408         }
409         return newSearchResultFields;
410     }
411 
412     private List<SearchResultField> buildBibSearchResults(SolrDocument solrDocument, SearchResultField searchResultField) {
413         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
414          Object object = solrDocument.getFieldValue("bibIdentifier");
415         if (object instanceof String) {
416              SearchResultField newSearchResultField = new SearchResultField();
417              SolrDocument bibSolrDocument = getBibRecord((String) object);
418             if (bibSolrDocument != null) {
419                 String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
420                 String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
421                 if (StringUtils.isNotBlank(resultFieldValue)) {
422                     newSearchResultField.setFieldValue(resultFieldValue);
423                 }
424                 newSearchResultField.setDocType(searchResultField.getDocType());
425                 newSearchResultField.setFieldName(searchResultField.getFieldName());
426                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
427                 newSearchResultFields.add(newSearchResultField);
428             }
429         } else {
430             if (((List) object) != null) {
431                 for (Object bibIdentifier : (List) object) {
432                     SearchResultField newSearchResultField = new SearchResultField();
433                     SolrDocument bibSolrDocument = getBibRecord((String) bibIdentifier);
434                     if (bibSolrDocument != null) {
435                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
436                         String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
437                         if (StringUtils.isNotBlank(resultFieldValue)) {
438                             newSearchResultField.setFieldValue(resultFieldValue);
439                         }
440                         newSearchResultField.setDocType(searchResultField.getDocType());
441                         newSearchResultField.setFieldName(searchResultField.getFieldName());
442                         //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
443                         newSearchResultFields.add(newSearchResultField);
444                     }
445                 }
446             }
447         }
448         return newSearchResultFields;
449     }
450 
451     private List<SearchResultField> buildItemSearchResultsForHoldings(SolrDocument solrDocument, SearchResultField searchResultField) {
452         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
453         Object object = solrDocument.getFieldValue("itemIdentifier");
454         if (object instanceof String) {
455             SearchResultField newSearchResultField = new SearchResultField();
456             SolrDocument itemSolrDocument = getItemRecord((String) object);
457             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
458             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
459             if (StringUtils.isNotBlank(resultFieldValue)) {
460                 newSearchResultField.setFieldValue(resultFieldValue);
461             }
462             newSearchResultField.setDocType(searchResultField.getDocType());
463             newSearchResultField.setFieldName(searchResultField.getFieldName());
464             //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
465             newSearchResultFields.add(newSearchResultField);
466         } else {
467             if (((List) object) != null) {
468                 for (Object identifier : (List) object) {
469                     SearchResultField newSearchResultField = new SearchResultField();
470                     SolrDocument itemSolrDocument = getItemRecord((String) identifier);
471                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
472                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
473                     if (StringUtils.isNotBlank(resultFieldValue)) {
474                         newSearchResultField.setFieldValue(resultFieldValue);
475                     }
476                     newSearchResultField.setDocType(searchResultField.getDocType());
477                     newSearchResultField.setFieldName(searchResultField.getFieldName());
478                     //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
479                     newSearchResultFields.add(newSearchResultField);
480                 }
481             }
482         }
483         return newSearchResultFields;
484     }
485 
486     private List<SearchResultField> buildItemSearchResultsForBib(SolrDocument solrDocument, SearchResultField searchResultField) {
487         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
488         Object holdingsObject = solrDocument.getFieldValue("holdingsIdentifier");
489         if (holdingsObject instanceof String) {
490             SearchResultField newSearchResultField = new SearchResultField();
491             SolrDocument holdingsSolrDocument = getHoldingsRecord((String) holdingsObject);
492             if (holdingsSolrDocument != null) {
493                 Object itemObject = holdingsSolrDocument.getFieldValue("itemIdentifier");
494                 if (itemObject instanceof String) {
495                     SolrDocument itemSolrDocument = getItemRecord((String) itemObject);
496                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
497                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
498                     if (StringUtils.isNotBlank(resultFieldValue)) {
499                         newSearchResultField.setFieldValue(resultFieldValue);
500                     }
501                     newSearchResultField.setDocType(searchResultField.getDocType());
502                     newSearchResultField.setFieldName(searchResultField.getFieldName());
503                     //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
504                     newSearchResultFields.add(newSearchResultField);
505                 } else {
506                     if (((List) itemObject) != null) {
507                         for (Object identifier : (List) itemObject) {
508                             SearchResultField newSearchResultField1 = new SearchResultField();
509                             SolrDocument itemSolrDocument = getItemRecord((String) identifier);
510                             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
511                             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
512                             if (StringUtils.isNotBlank(resultFieldValue)) {
513                                 newSearchResultField.setFieldValue(resultFieldValue);
514                             }
515                             newSearchResultField1.setDocType(searchResultField.getDocType());
516                             newSearchResultField1.setFieldName(searchResultField.getFieldName());
517                             //newSearchResultField1.setFieldValue(searchResultField.getFieldValue());
518                             newSearchResultFields.add(newSearchResultField1);
519                         }
520                     }
521                 }
522             }
523         } else {
524             if (((List) holdingsObject) != null) {
525                 for (Object identifier : (List) holdingsObject) {
526                     SearchResultField newSearchResultField = new SearchResultField();
527                     SolrDocument holdingsSolrDocument = getHoldingsRecord((String) identifier);
528                     if (holdingsSolrDocument != null) {
529                         Object itemObject = holdingsSolrDocument.getFieldValue("itemIdentifier");
530                         if (itemObject instanceof String) {
531                             SolrDocument itemSolrDocument = getItemRecord((String) itemObject);
532                             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
533                             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
534                             if (StringUtils.isNotBlank(resultFieldValue)) {
535                                 searchResultField.setFieldValue(resultFieldValue);
536                             }
537                             newSearchResultField.setDocType(searchResultField.getDocType());
538                             newSearchResultField.setFieldName(searchResultField.getFieldName());
539                             newSearchResultField.setFieldValue(searchResultField.getFieldValue());
540                             newSearchResultFields.add(newSearchResultField);
541                         } else {
542                             if (((List) itemObject) != null) {
543                                 for (Object itemIdentifier : (List) itemObject) {
544                                     SearchResultField newSearchResultField1 = new SearchResultField();
545                                     SolrDocument itemSolrDocument = getItemRecord((String) itemIdentifier);
546                                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
547                                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
548                                     if (StringUtils.isNotBlank(resultFieldValue)) {
549                                         searchResultField.setFieldValue(resultFieldValue);
550                                     }
551                                     newSearchResultField1.setDocType(searchResultField.getDocType());
552                                     newSearchResultField1.setFieldName(searchResultField.getFieldName());
553                                     newSearchResultField1.setFieldValue(searchResultField.getFieldValue());
554                                     newSearchResultFields.add(newSearchResultField1);
555                                 }
556                             }
557                         }
558                     }
559                 }
560             }
561         }
562         return newSearchResultFields;
563     }
564 
565     private List<SearchResultField> buildHoldingsSearchResults(SolrDocument solrDocument, SearchResultField searchResultField) {
566         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
567         Object object = solrDocument.getFieldValue("holdingsIdentifier");
568         if (object instanceof String) {
569             SearchResultField newSearchResultField = new SearchResultField();
570             SolrDocument holdingsSolrDocument = getHoldingsRecord((String) object);
571             if (holdingsSolrDocument != null) {
572                 String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
573                 String resultFieldValue = getSolrFieldValue(holdingsSolrDocument, fieldValue);
574                 if (StringUtils.isNotBlank(resultFieldValue)) {
575                     newSearchResultField.setFieldValue(resultFieldValue);
576                 }
577                 newSearchResultField.setDocType(searchResultField.getDocType());
578                 newSearchResultField.setFieldName(searchResultField.getFieldName());
579                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
580                 newSearchResultFields.add(newSearchResultField);
581             }
582         } else {
583             if (((List) object) != null) {
584                 for (Object identifier : (List) object) {
585                     SearchResultField newSearchResultField = new SearchResultField();
586                     SolrDocument holdingsSolrDocument = getHoldingsRecord((String) identifier);
587                     if (holdingsSolrDocument != null) {
588                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
589                         String resultFieldValue = getSolrFieldValue(holdingsSolrDocument, fieldValue);
590                         if (StringUtils.isNotBlank(resultFieldValue)) {
591                             newSearchResultField.setFieldValue(resultFieldValue);
592                         }
593                         newSearchResultField.setDocType(searchResultField.getDocType());
594                         newSearchResultField.setFieldName(searchResultField.getFieldName());
595                         //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
596                         newSearchResultFields.add(newSearchResultField);
597                     }
598                 }
599             }
600         }
601         return newSearchResultFields;
602     }
603 
604     private String getSolrFieldValue(SolrDocument solrDocument, String fieldValue) {
605         Object obj = solrDocument.getFieldValue(fieldValue);
606         String resultFieldValue = null;
607         if (obj instanceof String) {
608             resultFieldValue = (String) obj;
609         } else if (obj instanceof Boolean) {
610             resultFieldValue = String.valueOf(obj);
611         } else if (obj instanceof Date) {
612             resultFieldValue = String.valueOf(obj);
613         } else if (obj instanceof List) {
614             if(fieldValue.endsWith("_display")) {
615                 if (((List) obj) != null) {
616                     StringBuilder resultFieldList = new StringBuilder();
617                     ArrayList<String> fields = (ArrayList<String>) obj;
618                     for(String s : fields) {
619                         resultFieldList.append(s);
620                         resultFieldList.append(", ");
621                     }
622                     resultFieldValue = resultFieldList.substring(0, (resultFieldList.length() -1));
623                 }
624             }
625             else {
626                 resultFieldValue = (String) ((List) obj).get(0);
627             }
628         }
629         return resultFieldValue;
630     }
631 
632     private List<SearchResultField> getDefaultSearchResultFields(SearchParams searchParams) {
633         String docType = null;
634         if (!CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
635             docType = searchParams.getSearchConditions().get(0).getSearchField().getDocType();
636         }
637         List<SearchResultField> searchResultFields = new ArrayList<>();
638         if (StringUtils.isBlank(docType)) {
639             String allFields = BIB_FIELDS + "," + HOLDINGS_FIELDS + "," + ITEM_FIELDS;
640             for (String defaultField : getDefaultFields(allFields)) {
641                 SearchResultField searchResultField = new SearchResultField();
642                 searchResultField.setDocType(docType);
643                 searchResultField.setFieldName(defaultField);
644                 searchResultFields.add(searchResultField);
645             }
646         } else if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
647             for (String bibField : getDefaultFields(BIB_FIELDS)) {
648                 SearchResultField searchResultField = new SearchResultField();
649                 searchResultField.setDocType(docType);
650                 searchResultField.setFieldName(bibField);
651                 searchResultFields.add(searchResultField);
652             }
653         } else if (docType.equalsIgnoreCase(HOLDINGS)) {
654             for (String holdingsField : getDefaultFields(HOLDINGS_FIELDS)) {
655                 SearchResultField searchResultField = new SearchResultField();
656                 searchResultField.setDocType(docType);
657                 searchResultField.setFieldName(holdingsField);
658                 searchResultFields.add(searchResultField);
659             }
660         } else if (docType.equalsIgnoreCase(ITEM)) {
661             for (String itemField : getDefaultFields(ITEM_FIELDS)) {
662                 SearchResultField searchResultField = new SearchResultField();
663                 searchResultField.setDocType(docType);
664                 searchResultField.setFieldName(itemField);
665                 searchResultFields.add(searchResultField);
666             }
667         } else if (docType.equalsIgnoreCase(EHOLDINGS)) {
668             for (String itemField : getDefaultFields(EHOLDINGS_FIELDS)) {
669                 SearchResultField searchResultField = new SearchResultField();
670                 searchResultField.setDocType(docType);
671                 searchResultField.setFieldName(itemField);
672                 searchResultFields.add(searchResultField);
673             }
674         }
675         return searchResultFields;
676     }
677 
678     private List<String> getDefaultFields(String bibFields) {
679         return Arrays.asList(bibFields.split(","));
680     }
681 
682 
683     public String buildQueryWithSearchParams(SearchParams searchParams) {
684         return buildQueryWithSearchConditions(searchParams.getSearchConditions()) /*+ buildQueryWithSortConditions(searchParams.getSortConditions())*/;
685     }
686 
687     private SolrDocument getItemRecord(String itemIdentifier) {
688         try {
689             SolrDocument itemSolrDocument = null;
690             SearchParams searchParams = new SearchParams();
691             SearchField searchField = searchParams.buildSearchField("item", "itemIdentifier", itemIdentifier);
692             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
693             SolrQuery solrQuery = new SolrQuery();
694             SolrServer server = SolrServerManager.getInstance().getSolrServer();
695             buildQueryWithSearchConditions(searchParams,solrQuery);
696             QueryResponse response = server.query(solrQuery);
697             if (response.getResults().size() > 0) {
698                 itemSolrDocument = response.getResults().get(0);
699             }
700             return itemSolrDocument;
701         } catch (SolrServerException ex) {
702             LOG.info("Exception :", ex);
703             throw new DocstoreIndexException(ex.getMessage());
704         }
705     }
706 
707     private SolrDocument getBibRecord(String bibIdentifier) {
708         try {
709             SolrDocument bibSolrDocument = null;
710             SearchParams searchParams = new SearchParams();
711             SearchField searchField = searchParams.buildSearchField("bibliographic", "LocalId_search", DocumentUniqueIDPrefix.getDocumentId(bibIdentifier));
712             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
713             SolrQuery solrQuery = new SolrQuery();
714             SolrServer server = SolrServerManager.getInstance().getSolrServer();
715             buildQueryWithSearchConditions(searchParams,solrQuery);
716             QueryResponse response = server.query(solrQuery);
717             if (response.getResults().size() > 0) {
718                 bibSolrDocument = response.getResults().get(0);
719             }
720             return bibSolrDocument;
721         } catch (SolrServerException ex) {
722             LOG.info("Exception :", ex);
723             throw new DocstoreIndexException(ex.getMessage());
724         }
725     }
726 
727     private SolrDocument getHoldingsRecord(String holdingsIdentifier) {
728         try {
729             SolrDocument holdingsSolrDocument = null;
730             SearchParams searchParams = new SearchParams();
731             SearchField searchField = searchParams.buildSearchField("holdings", "holdingsIdentifier", holdingsIdentifier);
732             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
733             SolrQuery solrQuery = new SolrQuery();
734             SolrServer server = SolrServerManager.getInstance().getSolrServer();
735             buildQueryWithSearchConditions(searchParams,solrQuery);
736             QueryResponse response = server.query(solrQuery);
737             if (response.getResults().size() > 0) {
738                 holdingsSolrDocument = response.getResults().get(0);
739             }
740             return holdingsSolrDocument;
741         } catch (SolrServerException ex) {
742             LOG.info("Exception :", ex);
743             throw new DocstoreIndexException(ex.getMessage());
744         }
745     }
746 
747     private String buildQueryWithResultFieldsLists(SearchParams searchParams) {
748         String docType = searchParams.getDocType();
749         List<SearchResultField> searchResultFields = searchParams.getSearchResultFields();
750         if (StringUtils.isEmpty(docType) && !CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
751             for(SearchCondition searchCondition:searchParams.getSearchConditions()){
752                 if(searchCondition.getSearchField()!=null){
753                     docType = searchCondition.getSearchField().getDocType();
754                     break;
755                 }
756             }
757         }
758         StringBuffer resultFieldsBuffer = new StringBuffer();
759         //resultFieldsBuffer.append("&");
760         //resultFieldsBuffer.append("fl=");
761         if (StringUtils.isBlank(docType)) {
762             if (!CollectionUtils.isEmpty(searchResultFields)) {
763                 for (int i = 0; i < searchResultFields.size(); i++) {
764                     resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
765                     if (i != searchResultFields.size() - 1) {
766                         resultFieldsBuffer.append(",");
767                     }
768                 }
769             } /*else {
770                 resultFieldsBuffer.append(BIB_FIELDS + "," + HOLDINGS_FIELDS + "," + ITEM_FIELDS);
771             }*/
772         } else if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
773             if (!CollectionUtils.isEmpty(searchResultFields)) {
774                 for (int i = 0; i < searchResultFields.size(); i++) {
775                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(BIBLIOGRAPHIC)) {
776                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
777                         resultFieldsBuffer.append(",");
778                     }
779                 }
780                 resultFieldsBuffer.append(BIB_LINK_FIELDS);
781             } /*else {
782                 resultFieldsBuffer.append(BIB_FIELDS);
783             }*/
784         } else if (docType.equalsIgnoreCase(HOLDINGS)) {
785             if (!CollectionUtils.isEmpty(searchResultFields)) {
786                 for (int i = 0; i < searchResultFields.size(); i++) {
787                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(HOLDINGS)) {
788                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
789                         resultFieldsBuffer.append(",");
790                     }
791                 }
792                 resultFieldsBuffer.append(HOLDINGS_LINK_FIELDS);
793             } /*else {
794                 resultFieldsBuffer.append(HOLDINGS_FIELDS);
795             }*/
796 
797         } else if (docType.equalsIgnoreCase(ITEM)) {
798             if (!CollectionUtils.isEmpty(searchResultFields)) {
799                 for (int i = 0; i < searchResultFields.size(); i++) {
800                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(ITEM)) {
801                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
802                         resultFieldsBuffer.append(",");
803                     }
804                 }
805                 resultFieldsBuffer.append(ITEM_LINK_FIELDS);
806             } /*else {
807                 resultFieldsBuffer.append(ITEM_FIELDS);
808             }*/
809         } else if (docType.equalsIgnoreCase(EHOLDINGS)) {
810             if (!CollectionUtils.isEmpty(searchResultFields)) {
811                 for (int i = 0; i < searchResultFields.size(); i++) {
812                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(EHOLDINGS)) {
813                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
814                         resultFieldsBuffer.append(",");
815                     }
816                 }
817                 resultFieldsBuffer.append(EHOLDINGS_FIELDS);
818             } /*else {
819                 resultFieldsBuffer.append(ITEM_FIELDS);
820             }*/
821         }
822         return resultFieldsBuffer.toString();
823     }
824 
825     private List<String> getIds(List<SolrDocument> solrDocumentList) {
826         List<String> ids = new ArrayList<>();
827         for (SolrDocument solrDocument : solrDocumentList) {
828             String docType = (String) solrDocument.getFieldValue("DocType");
829             if (docType.equalsIgnoreCase(DocType.BIB.getCode())) {
830                 ids.add((String) solrDocument.getFieldValue("id"));
831             } else if (docType.equalsIgnoreCase(DocType.HOLDINGS.getCode())) {
832                 ids.add((String) solrDocument.getFieldValue("id"));
833             } else if (docType.equalsIgnoreCase(DocType.ITEM.getCode())) {
834                 ids.add((String) solrDocument.getFieldValue("id"));
835             }
836         }
837         return ids;
838     }
839 
840     public String buildQueryWithSearchConditions(List<SearchCondition> searchConditions) {
841         StringBuffer query = new StringBuffer();
842         StringBuffer addDocType = new StringBuffer();
843         if (searchConditions != null && searchConditions.size() > 0) {
844             for (SearchCondition searchCondition : searchConditions) {
845                 if (searchCondition.getSearchField() != null && searchCondition.getSearchField().getDocType() != null) {
846                     addDocType.append("(DocType:");
847                     addDocType.append(searchCondition.getSearchField().getDocType());
848                     addDocType.append(")");
849                     break;
850                 }
851             }
852         } else {
853             return "(*:*)";
854         }
855         Collections.reverse(searchConditions);
856         int size = searchConditions.size();
857 
858         String previousOperator = "";
859         for(int i= size-1 ; i >= 0 ; i--) {
860 
861             boolean isInsert = false;
862 
863             SearchCondition searchCondition = null;
864             String searchText =null;
865             String searchScope = null;
866 
867             if(searchConditions.get(i)!=null  && searchConditions.get(i).getSearchField() !=null){
868                 if((size-1) != i ) {
869                     query.insert(0, "(");
870                     isInsert = true;
871                 }
872                 searchCondition = searchConditions.get(i);
873                 searchText = searchCondition.getSearchField().getFieldValue();
874                 searchScope = searchCondition.getSearchScope();
875             }else{
876                 continue;
877             }
878 
879             if(isInsert) {
880                 query.append(previousOperator);
881             }
882             if (StringUtils.isNotBlank(searchCondition.getOperator())&&searchCondition.getOperator().equalsIgnoreCase("not")) {
883                 query.append("!");
884             }
885             query.append("(");
886             if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName())) {
887                 if (searchCondition.getSearchField().getFieldName().equalsIgnoreCase("all") || searchCondition.getSearchField().getFieldName().equalsIgnoreCase("any")) {
888                     query.append("all_text");
889                 } else {
890                     query.append(searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) != null ? searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) : searchCondition.getSearchField().getFieldName());
891                 }
892                 query.append(":");
893             }
894 
895             if (StringUtils.isNotBlank(searchText)) {
896                 String searchTextVal = getModifiedText(searchText);
897                 if (searchText.length() > 0) {
898                     query.append("(");
899                     if (StringUtils.isNotBlank(searchScope)) {
900                         if (searchScope.equalsIgnoreCase("AND")) {
901                             searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ AND +");
902                         } else if (searchScope.equalsIgnoreCase("OR")) {
903                             searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ OR +");
904                         } else if (searchScope.equalsIgnoreCase("phrase")) {
905                             searchTextVal = "\"" + searchText + "\"";
906                         } else if (searchScope.equalsIgnoreCase("none")) {
907                             searchTextVal = searchText;
908                         }
909                     }
910                     query.append(searchTextVal);
911                     query.append(")");
912                 }
913                 query.append(")");
914             }
915             else {
916                 query.append("(*:*)");
917                 query.append(")");
918             }
919             if(StringUtils.isNotBlank(searchCondition.getOperator())&&searchCondition.getOperator().equalsIgnoreCase("not")){
920                 previousOperator="AND";
921             } else {
922                 previousOperator = searchCondition.getOperator();
923             }
924             if(isInsert) {
925                 query.append(")");
926             }
927         }
928         if (addDocType != null && addDocType.length() > 0) {
929             return addDocType.append("AND").append(query).toString();
930         } else {
931             return query.toString();
932         }
933     }
934 
935 
936     public void buildQueryWithSearchConditions(SearchParams searchParams, SolrQuery solrQuery) {
937         String docType = searchParams.getDocType(); // second
938         String key = "";
939         String firstDocType = "";
940         String secondDocType = "";
941         String query = "";
942         List<SearchCondition> filterSearchConditions = new ArrayList<>();
943         List<SearchCondition> querySearchConditions = new ArrayList<>();
944         int size = searchParams.getSearchConditions().size();
945         for (int i = size - 1; i >= 0; i--) {
946             SearchCondition searchCondition = searchParams.getSearchConditions().get(i);
947             if (searchCondition.getSearchField() != null && searchCondition.getSearchField().getDocType() != null && docType.equals(searchCondition.getSearchField().getDocType())) {
948                 filterSearchConditions.add(searchCondition);
949                 firstDocType = searchCondition.getSearchField().getDocType();
950             } else {
951                 querySearchConditions.add(searchCondition);
952                 firstDocType = searchCondition.getSearchField().getDocType();
953             }
954         }
955         if (StringUtils.isEmpty(secondDocType)) {
956             secondDocType = docType;
957         }
958 
959         if (StringUtils.isEmpty(secondDocType)) {
960             secondDocType = firstDocType;
961         }
962         if(StringUtils.isEmpty(docType)){
963             docType=firstDocType;
964         }
965         if (StringUtils.isNotEmpty(firstDocType) && StringUtils.isNotEmpty(secondDocType)) {
966             key = secondDocType + firstDocType;
967             String crossDocumentJoinQuery=joinQueryMap.get(key);
968             if(StringUtils.isNotEmpty(crossDocumentJoinQuery)){
969                 query = joinQueryMap.get(key) + buildQueryWithSearchConditions(querySearchConditions);
970             }else{
971                 query =  buildQueryWithSearchConditions(querySearchConditions);
972             }
973 
974             String filterQuery = "";
975             if (filterSearchConditions != null && filterSearchConditions.size() > 0) {
976                 filterQuery = buildQueryWithSearchConditions(filterSearchConditions);
977             }
978             if (StringUtils.isEmpty(filterQuery)) {
979                 filterQuery = "DocType:" + docType;
980             }
981             solrQuery.setQuery(query);
982             solrQuery.setFilterQueries(filterQuery);
983             LOG.info("join query = " + solrQuery.getQuery() + "\tfilter query = " + solrQuery.getFilterQueries()[0]);
984         } else {
985             String filterQuery = buildQueryWithSearchConditions(filterSearchConditions);
986             solrQuery.setQuery(filterQuery);
987             LOG.info("query = " + solrQuery.getQuery());
988         }
989 
990     }
991 
992 
993 //    public String buildQueryWithSearchConditions(List<SearchCondition> searchConditions) {
994 //        boolean searchConditionCheck = false;
995 //        SearchCondition searchCondition = null;
996 //        String docType = null;
997 //        StringBuffer queryStringBuffer = new StringBuffer();
998 //        if (searchConditions != null && searchConditions.size() > 0) {
999 //            for (int i = 0; i < searchConditions.size(); i++) {
1000 //                int searchScopeAddLimit = i;
1001 //                searchCondition = searchConditions.get(i);
1002 //                if (searchCondition.getSearchField() != null) {
1003 //                    if (StringUtils.isBlank(docType) && searchScopeAddLimit == 0) {
1004 //                        docType = searchCondition.getSearchField().getDocType();
1005 //                        if (StringUtils.isNotBlank(docType)) {
1006 //                            queryStringBuffer.append("(");
1007 //                            queryStringBuffer.append("DocType:" + docType);
1008 //                            queryStringBuffer.append(")");
1009 //                        }
1010 //                    }
1011 //                    String searchScope = searchCondition.getSearchScope();
1012 //                    String searchOperator = searchCondition.getOperator();
1013 //                    String searchText = searchCondition.getSearchField().getFieldValue();
1014 //                    if (StringUtils.isBlank(docType) || docType.equalsIgnoreCase(searchCondition.getSearchField().getDocType())) {
1015 //                        if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName()) || StringUtils.isNotBlank(searchCondition.getSearchField().getFieldValue())) {
1016 //                            if (StringUtils.isNotBlank(docType) && searchScopeAddLimit == 0) {
1017 //                                queryStringBuffer.append("AND");
1018 //                                queryStringBuffer.append("(");
1019 //                            }
1020 //                            queryStringBuffer.append("(");
1021 //                            if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName())) {
1022 //                                if (searchCondition.getSearchField().getFieldName().equalsIgnoreCase("all")) {
1023 //                                    queryStringBuffer.append("all_text");
1024 //                                } else {
1025 //                                    queryStringBuffer.append(searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) != null ? searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) : searchCondition.getSearchField().getFieldName());
1026 //                                }
1027 //                                queryStringBuffer.append(":");
1028 //                            }
1029 //
1030 //                            if (StringUtils.isNotBlank(searchText)) {
1031 //                                String searchTextVal = getModifiedText(searchText);
1032 //                                if (searchText.length() > 0) {
1033 //                                    queryStringBuffer.append("(");
1034 //                                    if (StringUtils.isNotBlank(searchScope)) {
1035 //                                        if (searchScope.equalsIgnoreCase("AND")) {
1036 //                                            searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ AND +");
1037 //                                        } else if (searchScope.equalsIgnoreCase("OR")) {
1038 //                                            searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ OR +");
1039 //                                        } else if (searchScope.equalsIgnoreCase("phrase")) {
1040 //                                            searchTextVal = "\"" + searchText + "\"";
1041 //                                        } else if (searchScope.equalsIgnoreCase("none")) {
1042 //                                            searchTextVal = searchText;
1043 //                                        }
1044 //                                    }
1045 //                                    queryStringBuffer.append(searchTextVal);
1046 //                                    queryStringBuffer.append(")");
1047 //                                }
1048 //                                queryStringBuffer.append(")");
1049 //                                searchConditionCheck = true;
1050 //                            } else {
1051 //                                queryStringBuffer.append("(*:*)");
1052 //                                queryStringBuffer.append(")");
1053 //                                searchConditionCheck = true;
1054 //                            }
1055 //                        }
1056 //                    }
1057 //                    ++searchScopeAddLimit;
1058 //                    if (StringUtils.isBlank(searchOperator)) {
1059 //                        break;
1060 //                    }
1061 //                    if (searchScopeAddLimit != searchConditions.size()) {
1062 //                        if (StringUtils.isBlank(docType) || StringUtils.isNotBlank(docType) && docType.equalsIgnoreCase(searchConditions.get(searchScopeAddLimit).getSearchField().getDocType())) {
1063 //                            queryStringBuffer.append(searchOperator);
1064 //                        }
1065 //                    }
1066 //                }
1067 //                if (StringUtils.isBlank(docType) && StringUtils.isBlank(searchCondition.getSearchField().getFieldName()) && StringUtils.isBlank(searchCondition.getSearchField().getFieldValue())) {
1068 //                    queryStringBuffer.append("*:*");
1069 //                }
1070 //            }
1071 //        } else {
1072 //            queryStringBuffer.append("*:*");
1073 //        }
1074 //        if (searchConditionCheck && StringUtils.isNotBlank(docType)) {
1075 //            queryStringBuffer.append(")");
1076 //        }
1077 //        return queryStringBuffer.toString();
1078 //    }
1079 
1080     private String getModifiedText(String searchText) {
1081         StringBuffer modifiedText = new StringBuffer();
1082         StringCharacterIterator stringCharacterIterator = new StringCharacterIterator(searchText);
1083         char character = stringCharacterIterator.current();
1084         while (character != CharacterIterator.DONE) {
1085 
1086             if (character == '\\') {
1087                 modifiedText.append("\\\\");
1088             } else if (character == '?') {
1089                 modifiedText.append("\\?");
1090             } else if (character == '*' && StringUtils.isEmpty(modifiedText.toString())) {
1091                 modifiedText.append("\\*");
1092             } else if (character == '+') {
1093                 modifiedText.append("\\+");
1094             } else if (character == ':') {
1095                 modifiedText.append("\\:");
1096             } else if (character == '{') {
1097                 modifiedText.append("\\{");
1098             } else if (character == '}') {
1099                 modifiedText.append("\\}");
1100             } else if (character == '[') {
1101                 modifiedText.append("\\[");
1102             } else if (character == ']') {
1103                 modifiedText.append("\\]");
1104             } else if (character == '(') {
1105                 modifiedText.append("\\(");
1106             } else if (character == ')') {
1107                 modifiedText.append("\\)");
1108             } else if (character == '^') {
1109                 modifiedText.append("\\^");
1110             } else if (character == '~') {
1111                 modifiedText.append("\\~");
1112             } else if (character == '-') {
1113                 modifiedText.append("\\-");
1114             } else if (character == '!') {
1115                 modifiedText.append("\\!");
1116             } else if (character == '\'') {
1117                 modifiedText.append("\\'");
1118             } else if (character == '@') {
1119                 modifiedText.append("\\@");
1120             } else if (character == '#') {
1121                 modifiedText.append("\\#");
1122             } else if (character == '$') {
1123                 modifiedText.append("\\$");
1124             } else if (character == '%') {
1125                 modifiedText.append("\\%");
1126             } else {
1127                 // the char is not a special one
1128                 // add it to the result as is
1129                 modifiedText.append(character);
1130             }
1131             character = stringCharacterIterator.next();
1132         }
1133         return modifiedText.toString().toLowerCase();
1134     }
1135 
1136     /*public String buildQueryWithSortConditions(List<SortCondition> sortConditions) {
1137         StringBuffer sortFieldsQuery = new StringBuffer();
1138         for (SortCondition sortCondition : sortConditions) {
1139             String sortField = sortCondition.getSortField();
1140             String sortOrder = sortCondition.getSortOrder();
1141             if (StringUtils.isNotBlank(sortField) && StringUtils.isNotBlank(getSolrSortField(sortField.toUpperCase())) && StringUtils.isNotBlank(sortOrder)) {
1142                 sortFieldsQuery.append("&");
1143                 sortFieldsQuery.append("sort=");
1144                 sortFieldsQuery.append(getSolrSortField(sortField.toUpperCase()));
1145                 sortFieldsQuery.append(" ");
1146                 sortFieldsQuery.append(sortOrder);
1147             }
1148         }
1149         return sortFieldsQuery.toString();
1150     }*/
1151 
1152     private void buildQueryWithSortConditions(SolrQuery solrQuery, List<SortCondition> sortConditions) {
1153         for (SortCondition sortCondition : sortConditions) {
1154             String sortField = sortCondition.getSortField();
1155             String sortOrder = sortCondition.getSortOrder();
1156             if (StringUtils.isNotBlank(sortField) && StringUtils.isNotBlank(sortOrder)) {
1157                 solrQuery.addSortField(getSolrSortField(sortField.toUpperCase()) != null ? getSolrSortField(sortField.toUpperCase()) : sortField, SolrQuery.ORDER.valueOf(sortOrder));
1158             }
1159         }
1160     }
1161 
1162     private String getSolrSortField(String sortField) {
1163 
1164         if ("TITLE".equals(sortField)) {
1165             return "Title_sort";
1166         } else if ("AUTHOR".equals(sortField)) {
1167             return "Author_sort";
1168         } else if ("PUBLICATION DATE".equals(sortField)) {
1169             return "PublicationDate_sort";
1170         } else if ("LOCATION".equals(sortField)) {
1171             return "Location_sort";
1172         } else if ("CALL NUMBER".equals(sortField)) {
1173             return "CallNumber_sort";
1174         } else if ("LOCAL IDENTIFIER".equalsIgnoreCase(sortField)){
1175             return "LocalId_search";
1176         } else if ("Journal Title".equalsIgnoreCase(sortField)){
1177             return "JournalTitle_sort";
1178         }
1179         return null;
1180     }
1181 
1182     @Override
1183     public List<String> callNumberBrowse(BrowseParams browseParams) {
1184         try {
1185             SolrQuery solrQuery = new SolrQuery();
1186             SolrServer server = SolrServerManager.getInstance().getSolrServer();
1187             solrQuery.setQuery(buildQueryWithSearchParams(browseParams));
1188             QueryResponse response = server.query(solrQuery);
1189             browseParams.setTotalCount(response.getResults().getNumFound());
1190             return getIds(response.getResults());
1191         } catch (SolrServerException ex) {
1192             LOG.info("Exception :", ex);
1193             throw new DocstoreIndexException(ex.getMessage());
1194         }
1195     }
1196 
1197     @Override
1198     public String findBib(Map<String, String> map) {
1199         List<String> bibIds = new ArrayList<>();
1200         SearchParams searchParams = buildSearchParamsFromMap(map);
1201         SearchResponse searchResponse = search(searchParams);
1202         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1203             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1204                 bibIds.add(searchResultField.getFieldValue());
1205             }
1206         }
1207         if (!CollectionUtils.isEmpty(bibIds)) {
1208             return bibIds.get(0);
1209         }
1210         return null;
1211     }
1212 
1213     private SearchParams buildSearchParamsFromMap(Map<String, String> map) {
1214         SearchParams searchParams = new SearchParams();
1215         Set<String> keys = map.keySet();
1216         for (String key : keys) {
1217             if (!BibConstants.DOC_TYPE.equalsIgnoreCase(key)) {
1218                 SearchCondition searchCondition = new SearchCondition();
1219                 SearchField searchField = searchParams.buildSearchField(map.get(BibConstants.DOC_TYPE), searchFieldsMap.get(key), map.get(key));
1220                 searchCondition.setSearchField(searchField);
1221                 searchParams.getSearchConditions().add(searchCondition);
1222             }
1223         }
1224         searchParams.getSearchResultFields().add(searchParams.buildSearchResultField(map.get(BibConstants.DOC_TYPE), "id"));
1225         return searchParams;
1226     }
1227 
1228     @Override
1229     public String findHoldings(Map<String, String> map) {
1230         List<String> holdingIds = new ArrayList<>();
1231         map.put(BibConstants.DOC_TYPE, "holdings");
1232         SearchParams searchParams = buildSearchParamsFromMap(map);
1233         SearchResponse searchResponse = search(searchParams);
1234         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1235             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1236                 holdingIds.add(searchResultField.getFieldValue());
1237             }
1238         }
1239         if (!CollectionUtils.isEmpty(holdingIds)) {
1240             return holdingIds.get(0);
1241         }
1242         return null;
1243     }
1244 
1245     @Override
1246     public String findItem(Map<String, String> map) {
1247         List<String> itemIds = new ArrayList<>();
1248         map.put(BibConstants.DOC_TYPE, "item");
1249         SearchParams searchParams = buildSearchParamsFromMap(map);
1250         SearchResponse searchResponse = search(searchParams);
1251         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1252             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1253                 itemIds.add(searchResultField.getFieldValue());
1254             }
1255         }
1256         if (!CollectionUtils.isEmpty(itemIds)) {
1257             return itemIds.get(0);
1258         }
1259         return null;
1260     }
1261 
1262     @Override
1263     public String findHoldingsTree(Map<String, String> map) {
1264         return findHoldings(map);
1265     }
1266 
1267     @Override
1268     public String findBibTree(Map<String, String> map) {
1269         return findBib(map);
1270     }
1271 
1272 }