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

Last change on this file since 29142 was 29142, checked in by ak19, 10 years ago

Part of port from lucene3.3.0 to lucene4.7.2. Solr related. 1. Java and perl code changes for solr4.7.2; 2. Dr Bainbridge further fixed a bug in how the variable called running is set in solrserver.pm

  • 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.LuceneWrapper4.SharedSoleneQuery;
42import org.greenstone.LuceneWrapper4.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.