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

Last change on this file since 25931 was 25931, checked in by sjm84, 12 years ago

Some tidying and making Solr return some basic query information (the total docs found)

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