source: gs3-extensions/solr/trunk/src/src/java/org/greenstone/gsdl3/util/SolrQueryWrapper.java@ 28063

Last change on this file since 28063 was 28063, checked in by kjdon, 11 years ago

adding in comments and sorting search results

  • Property svn:executable set to *
File size: 8.3 KB
Line 
1/**********************************************************************
2 *
3 * SolrQueryWrapper.java
4 *
5 * Copyright 2004 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *********************************************************************/
26package org.greenstone.gsdl3.util;
27
28import java.lang.reflect.Type;
29import java.net.URLDecoder;
30import java.util.ArrayList;
31import java.util.HashMap;
32import java.util.List;
33
34import org.apache.log4j.Logger;
35import org.apache.solr.client.solrj.SolrServer;
36import org.apache.solr.client.solrj.SolrServerException;
37import org.apache.solr.client.solrj.response.QueryResponse;
38import org.apache.solr.common.SolrDocument;
39import org.apache.solr.common.SolrDocumentList;
40import org.apache.solr.common.params.ModifiableSolrParams;
41import org.greenstone.LuceneWrapper3.SharedSoleneQuery;
42import org.greenstone.LuceneWrapper3.SharedSoleneQueryResult;
43
44import com.google.gson.Gson;
45import com.google.gson.reflect.TypeToken;
46
47public class SolrQueryWrapper extends SharedSoleneQuery
48{
49 public static String SORT_ASCENDING = "asc";
50 public static String SORT_DESCENDING = "desc";
51 public static String SORT_BY_RANK = "score";
52 public static String SORT_BY_INDEX_ORDER = "_docid_";
53
54 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SolrQueryWrapper.class.getName());
55 protected int max_docs = 100;
56 protected String sort_order = SORT_DESCENDING;
57 protected ArrayList<String> _facets = new ArrayList<String>();
58 protected ArrayList<String> _facetQueries = new ArrayList<String>();
59 SolrServer solr_core = null;
60
61 public SolrQueryWrapper()
62 {
63 super();
64 start_results = 0;
65 }
66
67 public void setMaxDocs(int max_docs)
68 {
69 this.max_docs = max_docs;
70 }
71
72 public void setSolrCore(SolrServer solr_core)
73 {
74 this.solr_core = solr_core;
75 }
76
77 public void setSortOrder(String order)
78 {
79 this.sort_order = order;
80 }
81 public void addFacet(String facet)
82 {
83 if (!_facets.contains(facet))
84 {
85 _facets.add(facet);
86 }
87 }
88
89 public void clearFacets()
90 {
91 _facets.clear();
92 }
93
94 public void addFacetQuery(String facetQuery)
95 {
96 if (!_facetQueries.contains(facetQuery))
97 {
98 _facetQueries.add(facetQuery);
99 }
100 }
101
102 public void clearFacetQueries()
103 {
104 _facetQueries.clear();
105 }
106
107 public boolean initialise()
108 {
109 if (solr_core == null)
110 {
111 utf8out.println("Solr Core not loaded in ");
112 utf8out.flush();
113 return false;
114 }
115 return true;
116 }
117
118 public SharedSoleneQueryResult runQuery(String query_string)
119 {
120 if (query_string == null || query_string.equals(""))
121 {
122 utf8out.println("The query word is not indicated ");
123 utf8out.flush();
124 return null;
125 }
126
127 SolrQueryResult solr_query_result = new SolrQueryResult();
128 solr_query_result.clear();
129
130 if (_facetQueries.size() > 0)
131 {
132 HashMap<String, ArrayList<String>> grouping = new HashMap<String, ArrayList<String>>();
133 for (String currentQuery : _facetQueries)
134 {
135 //Facet queries are stored in JSON, so we have to decode it
136 Gson gson = new Gson();
137 Type type = new TypeToken<List<String>>()
138 {
139 }.getType();
140 List<String> queryElems = gson.fromJson(currentQuery, type);
141
142 //Group each query segment by the index it uses
143 for (String currentQueryElement : queryElems)
144 {
145 String decodedQueryElement = null;
146 try
147 {
148 decodedQueryElement = URLDecoder.decode(currentQueryElement, "UTF-8");
149 }
150 catch (Exception ex)
151 {
152 continue;
153 }
154
155 int colonIndex = currentQueryElement.indexOf(":");
156 String indexShortName = currentQueryElement.substring(0, colonIndex);
157
158 if (grouping.get(indexShortName) == null)
159 {
160 grouping.put(indexShortName, new ArrayList<String>());
161 }
162 grouping.get(indexShortName).add(decodedQueryElement);
163 }
164 }
165
166 //Construct the facet query string to add to the regular query string
167 StringBuilder facetQueryString = new StringBuilder();
168 int keysetCounter = 0;
169 for (String key : grouping.keySet())
170 {
171 StringBuilder currentFacetString = new StringBuilder("(");
172 int groupCounter = 0;
173 for (String queryElem : grouping.get(key))
174 {
175 currentFacetString.append(queryElem);
176
177 groupCounter++;
178 if (groupCounter < grouping.get(key).size())
179 {
180 currentFacetString.append(" OR ");
181 }
182 }
183 currentFacetString.append(")");
184
185 facetQueryString.append(currentFacetString);
186
187 keysetCounter++;
188 if (keysetCounter < grouping.keySet().size())
189 {
190 facetQueryString.append(" AND ");
191 }
192 }
193
194 if (facetQueryString.length() > 0)
195 {
196 query_string += " AND " + facetQueryString;
197 }
198 }
199
200 ModifiableSolrParams solrParams = new ModifiableSolrParams();
201 solrParams.set("q", query_string);
202 // sort param, like "score desc" or "byORG asc"
203 solrParams.set("sort", this.sort_field+" "+this.sort_order);
204 // which result to start from
205 solrParams.set("start", start_results);
206 // how many results per "page"
207 solrParams.set("rows", (end_results - start_results) + 1);
208 // which fields to return for each document
209 solrParams.set("fl", "docOID score");
210 // turn on the termsComponent
211 solrParams.set("terms", true);
212 // which field to get the terms from
213 solrParams.set("terms.fl", "ZZ");
214
215 if (_facets.size() > 0)
216 {
217 // enable facet counts in the query response
218 solrParams.set("facet", "true");
219 for (int i = 0; i < _facets.size(); i++)
220 {
221 // add this field as a facet
222 solrParams.add("facet.field", _facets.get(i));
223 }
224 }
225
226 try
227 {
228 QueryResponse solrResponse = solr_core.query(solrParams);
229 SolrDocumentList hits = solrResponse.getResults();
230
231 if (hits != null)
232 {
233 logger.info("*** hits size = " + hits.size());
234 logger.info("*** num docs found = " + hits.getNumFound());
235
236 logger.info("*** start results = " + start_results);
237 logger.info("*** end results = " + end_results);
238 logger.info("*** max docs = " + max_docs);
239
240 // numDocsFound is the total number of matching docs in the collection
241 // as opposed to the number of documents returned in the hits list
242
243 solr_query_result.setTotalDocs((int) hits.getNumFound());
244
245 solr_query_result.setStartResults(start_results);
246 solr_query_result.setEndResults(start_results + hits.size());
247
248 int sepIndex = query_string.indexOf(":");
249 String field = query_string.substring(0, sepIndex);
250 String query = query_string.substring(sepIndex + 2, query_string.length() - 1);
251
252 solr_query_result.addTerm(query, field, (int) hits.getNumFound(), -1);
253
254 // Output the matching documents
255 for (int i = 0; i < hits.size(); i++)
256 {
257 SolrDocument doc = hits.get(i);
258
259 // Need to think about how to support document term frequency. Make zero for now
260 int doc_term_freq = 0;
261 String docOID = (String) doc.get("docOID");
262 Float score = (Float) doc.get("score");
263
264 logger.info("**** docOID = " + docOID);
265 logger.info("**** score = " + score);
266
267 solr_query_result.addDoc(docOID, score.floatValue(), doc_term_freq);
268 }
269 }
270 else
271 {
272 solr_query_result.setTotalDocs(0);
273
274 solr_query_result.setStartResults(0);
275 solr_query_result.setEndResults(0);
276 }
277
278 solr_query_result.setFacetResults(solrResponse.getFacetFields());
279 }
280 catch (SolrServerException server_exception)
281 {
282 server_exception.printStackTrace();
283 solr_query_result.setError(SolrQueryResult.SERVER_ERROR);
284 }
285
286 return solr_query_result;
287 }
288
289 //Greenstone universe operates with a base of 1 for "start_results"
290 //But Solr operates from 0
291 public void setStartResults(int start_results)
292 {
293 if (start_results < 0)
294 {
295 start_results = 0;
296 }
297 this.start_results = start_results - 1;
298 }
299
300 public void cleanUp()
301 {
302 super.cleanUp();
303 }
304}
Note: See TracBrowser for help on using the repository browser.