1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.solr.search;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Spliterator;
26 import java.util.function.Consumer;
27 import java.util.stream.Collectors;
28 import java.util.stream.Stream;
29 import java.util.stream.StreamSupport;
30
31 import org.apache.logging.log4j.LogManager;
32 import org.apache.logging.log4j.Logger;
33 import org.apache.solr.client.solrj.SolrClient;
34 import org.apache.solr.client.solrj.SolrQuery;
35 import org.apache.solr.client.solrj.SolrServerException;
36 import org.apache.solr.client.solrj.response.QueryResponse;
37 import org.apache.solr.common.SolrDocument;
38 import org.apache.solr.common.SolrDocumentList;
39 import org.apache.solr.common.params.ModifiableSolrParams;
40 import org.apache.solr.common.params.SolrParams;
41 import org.jdom2.Document;
42 import org.mycore.parsers.bool.MCRCondition;
43 import org.mycore.parsers.bool.MCROrCondition;
44 import org.mycore.parsers.bool.MCRSetCondition;
45 import org.mycore.services.fieldquery.MCRQuery;
46
47 import jakarta.servlet.http.HttpServletRequest;
48
49
50
51
52
53
54 public abstract class MCRSolrSearchUtils {
55
56 private static final Logger LOGGER = LogManager.getLogger(MCRQLSearchUtils.class);
57
58
59
60
61
62
63
64
65
66 public static SolrDocument first(SolrClient solrClient, String query) throws SolrServerException, IOException {
67 ModifiableSolrParams p = new ModifiableSolrParams();
68 p.set("q", query);
69 p.set("rows", 1);
70 QueryResponse response = solrClient.query(p);
71 return response.getResults().isEmpty() ? null : response.getResults().get(0);
72 }
73
74 @SuppressWarnings("rawtypes")
75 public static SolrQuery getSolrQuery(MCRQuery query, Document input, HttpServletRequest request) {
76 int rows = query.getNumPerPage();
77 List<String> returnFields = query.getReturnFields();
78 MCRCondition condition = query.getCondition();
79 HashMap<String, List<MCRCondition>> table;
80
81 if (condition instanceof MCRSetCondition) {
82 table = MCRConditionTransformer.groupConditionsByIndex((MCRSetCondition) condition);
83 } else {
84
85 LOGGER.warn("Condition is not SetCondition.");
86 table = new HashMap<>();
87
88 ArrayList<MCRCondition> conditionList = new ArrayList<>();
89 conditionList.add(condition);
90
91 table.put("metadata", conditionList);
92
93 }
94
95 boolean booleanAnd = !(condition instanceof MCROrCondition<?>);
96 SolrQuery mergedSolrQuery = MCRConditionTransformer.buildMergedSolrQuery(query.getSortBy(), false, booleanAnd,
97 table, rows, returnFields);
98 String qt = input.getRootElement().getAttributeValue("qt");
99 if (qt != null) {
100 mergedSolrQuery.setParam("qt", qt);
101 }
102
103 String mask = input.getRootElement().getAttributeValue("mask");
104 if (mask != null) {
105 mergedSolrQuery.setParam("mask", mask);
106 mergedSolrQuery.setParam("_session", request.getParameter("_session"));
107 }
108 return mergedSolrQuery;
109 }
110
111
112
113
114
115
116
117
118
119 public static List<String> listIDs(SolrClient solrClient, String query) {
120 ModifiableSolrParams p = new ModifiableSolrParams();
121 p.set("q", query);
122 p.set("fl", "id");
123 return stream(solrClient, p).map(doc -> doc.getFieldValue("id").toString()).collect(Collectors.toList());
124 }
125
126
127
128
129
130
131
132
133 public static Stream<SolrDocument> stream(SolrClient solrClient, SolrParams params) {
134 return stream(solrClient, params, true, 1000);
135 }
136
137 public static Stream<SolrDocument> stream(SolrClient solrClient, SolrParams params, boolean parallel,
138 int rowsPerRequest) {
139 SolrDocumentSpliterator solrDocumentSpliterator = new SolrDocumentSpliterator(solrClient, params, 0,
140 rowsPerRequest);
141 return StreamSupport.stream(solrDocumentSpliterator, parallel);
142 }
143
144
145
146
147 public static class SolrDocumentSpliterator implements Spliterator<SolrDocument> {
148
149 protected SolrClient solrClient;
150
151 protected SolrParams params;
152
153 protected long start;
154
155 protected long rows;
156
157 protected Long size;
158
159 protected QueryResponse response;
160
161 public SolrDocumentSpliterator(SolrClient solrClient, SolrParams params, long start, long rows) {
162 this(solrClient, params, start, rows, null);
163 }
164
165 public SolrDocumentSpliterator(SolrClient solrClient, SolrParams params, long start, long rows, Long size) {
166 this.solrClient = solrClient;
167 this.params = params;
168 this.start = start;
169 this.rows = rows;
170 this.size = size;
171 }
172
173 @Override
174 public int characteristics() {
175 return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
176 }
177
178 @Override
179 public long estimateSize() {
180 if (this.size == null) {
181 ModifiableSolrParams sizeParams = new ModifiableSolrParams(this.params);
182 sizeParams.set("start", 0);
183 sizeParams.set("rows", 0);
184 try {
185 QueryResponse response = solrClient.query(sizeParams);
186 this.size = response.getResults().getNumFound();
187 } catch (SolrServerException | IOException e) {
188 throw new IllegalStateException(e);
189 }
190 }
191 return this.size;
192 }
193
194 @Override
195 public void forEachRemaining(Consumer<? super SolrDocument> action) {
196 if (action == null) {
197 throw new NullPointerException();
198 }
199 ModifiableSolrParams p = new ModifiableSolrParams(params);
200 p.set("rows", (int) rows);
201 long start = this.start, size = estimateSize(), fetched = 0;
202 while (fetched < size) {
203 p.set("start", (int) (start + fetched));
204 response = query(p);
205 SolrDocumentList results = response.getResults();
206 for (SolrDocument doc : results) {
207 action.accept(doc);
208 }
209 fetched += results.size();
210 }
211 }
212
213 protected QueryResponse query(SolrParams params) {
214 try {
215 return solrClient.query(params);
216 } catch (SolrServerException | IOException e) {
217 throw new IllegalStateException(e);
218 }
219 }
220
221 @Override
222 public boolean tryAdvance(Consumer<? super SolrDocument> action) {
223 if (action == null) {
224 throw new NullPointerException();
225 }
226 long i = start, size = estimateSize();
227 if (size > 0) {
228 if (response == null) {
229 ModifiableSolrParams p = new ModifiableSolrParams(params);
230 p.set("start", (int) i);
231 p.set("rows", (int) rows);
232 response = query(p);
233 }
234 action.accept(response.getResults().get(response.getResults().size() - (int) size));
235 this.start = i + 1;
236 this.size -= 1;
237 return true;
238 }
239 return false;
240 }
241
242 @Override
243 public Spliterator<SolrDocument> trySplit() {
244 long s = estimateSize(), i = start, l = rows;
245 if (l >= s) {
246 return null;
247 }
248 this.size = l;
249 return new SolrDocumentSpliterator(solrClient, params, i + l, l, s - l);
250 }
251 }
252
253 }