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

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

set a default sort field, and make sure it is not being set to null

  • Property svn:executable set to *
File size: 8.5 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 String sort_field = SORT_BY_RANK; // don't want null default for solr
58 protected ArrayList<String> _facets = new ArrayList<String>();
59 protected ArrayList<String> _facetQueries = new ArrayList<String>();
60 SolrServer solr_core = null;
61
62 public SolrQueryWrapper()
63 {
64 super();
65 start_results = 0;
66 }
67
68 public void setMaxDocs(int max_docs)
69 {
70 this.max_docs = max_docs;
71 }
72
73 public void setSolrCore(SolrServer solr_core)
74 {
75 this.solr_core = solr_core;
76 }
77 // make sure its not null.
78 public void setSortField(String sort_field) {
79 if (sort_field != null) {
80 this.sort_field = sort_field;
81 }
82 }
83
84 public void setSortOrder(String order)
85 {
86 this.sort_order = order;
87 }
88 public void addFacet(String facet)
89 {
90 if (!_facets.contains(facet))
91 {
92 _facets.add(facet);
93 }
94 }
95
96 public void clearFacets()
97 {
98 _facets.clear();
99 }
100
101 public void addFacetQuery(String facetQuery)
102 {
103 if (!_facetQueries.contains(facetQuery))
104 {
105 _facetQueries.add(facetQuery);
106 }
107 }
108
109 public void clearFacetQueries()
110 {
111 _facetQueries.clear();
112 }
113
114 public boolean initialise()
115 {
116 if (solr_core == null)
117 {
118 utf8out.println("Solr Core not loaded in ");
119 utf8out.flush();
120 return false;
121 }
122 return true;
123 }
124
125 public SharedSoleneQueryResult runQuery(String query_string)
126 {
127 if (query_string == null || query_string.equals(""))
128 {
129 utf8out.println("The query word is not indicated ");
130 utf8out.flush();
131 return null;
132 }
133
134 SolrQueryResult solr_query_result = new SolrQueryResult();
135 solr_query_result.clear();
136
137 if (_facetQueries.size() > 0)
138 {
139 HashMap<String, ArrayList<String>> grouping = new HashMap<String, ArrayList<String>>();
140 for (String currentQuery : _facetQueries)
141 {
142 //Facet queries are stored in JSON, so we have to decode it
143 Gson gson = new Gson();
144 Type type = new TypeToken<List<String>>()
145 {
146 }.getType();
147 List<String> queryElems = gson.fromJson(currentQuery, type);
148
149 //Group each query segment by the index it uses
150 for (String currentQueryElement : queryElems)
151 {
152 String decodedQueryElement = null;
153 try
154 {
155 decodedQueryElement = URLDecoder.decode(currentQueryElement, "UTF-8");
156 }
157 catch (Exception ex)
158 {
159 continue;
160 }
161
162 int colonIndex = currentQueryElement.indexOf(":");
163 String indexShortName = currentQueryElement.substring(0, colonIndex);
164
165 if (grouping.get(indexShortName) == null)
166 {
167 grouping.put(indexShortName, new ArrayList<String>());
168 }
169 grouping.get(indexShortName).add(decodedQueryElement);
170 }
171 }
172
173 //Construct the facet query string to add to the regular query string
174 StringBuilder facetQueryString = new StringBuilder();
175 int keysetCounter = 0;
176 for (String key : grouping.keySet())
177 {
178 StringBuilder currentFacetString = new StringBuilder("(");
179 int groupCounter = 0;
180 for (String queryElem : grouping.get(key))
181 {
182 currentFacetString.append(queryElem);
183
184 groupCounter++;
185 if (groupCounter < grouping.get(key).size())
186 {
187 currentFacetString.append(" OR ");
188 }
189 }
190 currentFacetString.append(")");
191
192 facetQueryString.append(currentFacetString);
193
194 keysetCounter++;
195 if (keysetCounter < grouping.keySet().size())
196 {
197 facetQueryString.append(" AND ");
198 }
199 }
200
201 if (facetQueryString.length() > 0)
202 {
203 query_string += " AND " + facetQueryString;
204 }
205 }
206
207 ModifiableSolrParams solrParams = new ModifiableSolrParams();
208 solrParams.set("q", query_string);
209 // sort param, like "score desc" or "byORG asc"
210 solrParams.set("sort", this.sort_field+" "+this.sort_order);
211 // which result to start from
212 solrParams.set("start", start_results);
213 // how many results per "page"
214 solrParams.set("rows", (end_results - start_results) + 1);
215 // which fields to return for each document
216 solrParams.set("fl", "docOID score");
217 // turn on the termsComponent
218 solrParams.set("terms", true);
219 // which field to get the terms from
220 solrParams.set("terms.fl", "ZZ");
221
222 if (_facets.size() > 0)
223 {
224 // enable facet counts in the query response
225 solrParams.set("facet", "true");
226 for (int i = 0; i < _facets.size(); i++)
227 {
228 // add this field as a facet
229 solrParams.add("facet.field", _facets.get(i));
230 }
231 }
232
233 try
234 {
235 QueryResponse solrResponse = solr_core.query(solrParams);
236 SolrDocumentList hits = solrResponse.getResults();
237
238 if (hits != null)
239 {
240 logger.info("*** hits size = " + hits.size());
241 logger.info("*** num docs found = " + hits.getNumFound());
242
243 logger.info("*** start results = " + start_results);
244 logger.info("*** end results = " + end_results);
245 logger.info("*** max docs = " + max_docs);
246
247 // numDocsFound is the total number of matching docs in the collection
248 // as opposed to the number of documents returned in the hits list
249
250 solr_query_result.setTotalDocs((int) hits.getNumFound());
251
252 solr_query_result.setStartResults(start_results);
253 solr_query_result.setEndResults(start_results + hits.size());
254
255 int sepIndex = query_string.indexOf(":");
256 String field = query_string.substring(0, sepIndex);
257 String query = query_string.substring(sepIndex + 2, query_string.length() - 1);
258
259 solr_query_result.addTerm(query, field, (int) hits.getNumFound(), -1);
260
261 // Output the matching documents
262 for (int i = 0; i < hits.size(); i++)
263 {
264 SolrDocument doc = hits.get(i);
265
266 // Need to think about how to support document term frequency. Make zero for now
267 int doc_term_freq = 0;
268 String docOID = (String) doc.get("docOID");
269 Float score = (Float) doc.get("score");
270
271 logger.info("**** docOID = " + docOID);
272 logger.info("**** score = " + score);
273
274 solr_query_result.addDoc(docOID, score.floatValue(), doc_term_freq);
275 }
276 }
277 else
278 {
279 solr_query_result.setTotalDocs(0);
280
281 solr_query_result.setStartResults(0);
282 solr_query_result.setEndResults(0);
283 }
284
285 solr_query_result.setFacetResults(solrResponse.getFacetFields());
286 }
287 catch (SolrServerException server_exception)
288 {
289 server_exception.printStackTrace();
290 solr_query_result.setError(SolrQueryResult.SERVER_ERROR);
291 }
292
293 return solr_query_result;
294 }
295
296 //Greenstone universe operates with a base of 1 for "start_results"
297 //But Solr operates from 0
298 public void setStartResults(int start_results)
299 {
300 if (start_results < 0)
301 {
302 start_results = 0;
303 }
304 this.start_results = start_results - 1;
305 }
306
307 public void cleanUp()
308 {
309 super.cleanUp();
310 }
311}
Note: See TracBrowser for help on using the repository browser.