0
# Configuration and Utilities
1
2
This section covers supporting classes for document rating, search hit handling, query quality evaluation, configuration management, and plugin infrastructure.
3
4
## Document and Rating Classes
5
6
### RatedDocument
7
8
Represents a document with its relevance rating for a specific query.
9
10
```java { .api }
11
public class RatedDocument implements Writeable, ToXContentObject {
12
// Constructor
13
public RatedDocument(String index, String id, int rating);
14
15
// Property access
16
public DocumentKey getKey();
17
public int getRating();
18
19
// Serialization methods
20
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException;
21
public static RatedDocument fromXContent(XContentParser parser) throws IOException;
22
public void writeTo(StreamOutput out) throws IOException;
23
24
// Equality and comparison
25
public boolean equals(Object obj);
26
public int hashCode();
27
28
// Nested DocumentKey class
29
public static class DocumentKey {
30
public DocumentKey(String index, String id);
31
public String getIndex();
32
public String getId();
33
public boolean equals(Object obj);
34
public int hashCode();
35
}
36
}
37
```
38
39
**Usage:**
40
```java
41
// Create rated documents with different relevance levels
42
List<RatedDocument> ratedDocs = Arrays.asList(
43
new RatedDocument("products", "laptop_pro", 3), // highly relevant
44
new RatedDocument("products", "laptop_basic", 2), // relevant
45
new RatedDocument("products", "tablet", 1), // somewhat relevant
46
new RatedDocument("products", "phone", 0) // not relevant
47
);
48
49
// Access document properties
50
for (RatedDocument doc : ratedDocs) {
51
DocumentKey key = doc.getKey();
52
System.out.println("Document " + key.getId() + " in index " + key.getIndex() +
53
" has rating: " + doc.getRating());
54
}
55
```
56
57
### RatedSearchHit
58
59
Wrapper combining a search hit with its optional rating.
60
61
```java { .api }
62
public class RatedSearchHit implements Writeable, ToXContentObject {
63
// Constructor
64
public RatedSearchHit(SearchHit hit, OptionalInt rating);
65
66
// Property access
67
public SearchHit getSearchHit();
68
public OptionalInt getRating();
69
70
// Serialization methods
71
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException;
72
public void writeTo(StreamOutput out) throws IOException;
73
74
// Equality and comparison
75
public boolean equals(Object obj);
76
public int hashCode();
77
}
78
```
79
80
**Usage:**
81
```java
82
// Join search results with ratings
83
SearchHit[] searchHits = searchResponse.getHits().getHits();
84
List<RatedDocument> ratedDocs = getRatedDocuments();
85
86
List<RatedSearchHit> ratedSearchHits = EvaluationMetric.joinHitsWithRatings(searchHits, ratedDocs);
87
88
// Process rated search hits
89
for (RatedSearchHit ratedHit : ratedSearchHits) {
90
SearchHit hit = ratedHit.getSearchHit();
91
OptionalInt rating = ratedHit.getRating();
92
93
if (rating.isPresent()) {
94
System.out.println("Document " + hit.getId() + " has rating: " + rating.getAsInt());
95
} else {
96
System.out.println("Document " + hit.getId() + " is unrated");
97
}
98
}
99
```
100
101
## Query Evaluation Results
102
103
### EvalQueryQuality
104
105
Contains the evaluation result for a single query, including metric score and detailed breakdown.
106
107
```java { .api }
108
public class EvalQueryQuality implements ToXContentFragment, Writeable {
109
// Constructors
110
public EvalQueryQuality(String id, double metricScore);
111
public EvalQueryQuality(String id, double metricScore, MetricDetail optionalMetricDetails, List<RatedSearchHit> ratedHits);
112
113
// Property access
114
public String getId();
115
public double metricScore();
116
public MetricDetail getMetricDetails();
117
public List<RatedSearchHit> getHitsAndRatings();
118
119
// Mutation methods
120
public void setMetricDetails(MetricDetail breakdown);
121
public void addHitsAndRatings(List<RatedSearchHit> ratedSearchHits);
122
123
// Serialization methods
124
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException;
125
public static EvalQueryQuality fromXContent(XContentParser parser, String queryId) throws IOException;
126
public void writeTo(StreamOutput out) throws IOException;
127
128
// Comparison and equality
129
public boolean equals(Object obj);
130
public int hashCode();
131
}
132
```
133
134
**Usage:**
135
```java
136
// Access query evaluation results
137
Map<String, EvalQueryQuality> queryResults = response.getPartialResults();
138
139
for (Map.Entry<String, EvalQueryQuality> entry : queryResults.entrySet()) {
140
String queryId = entry.getKey();
141
EvalQueryQuality quality = entry.getValue();
142
143
// Get basic metrics
144
double score = quality.metricScore();
145
System.out.println("Query " + queryId + " score: " + String.format("%.4f", score));
146
147
// Access detailed breakdown if available
148
MetricDetail details = quality.getMetricDetails();
149
if (details != null) {
150
// Cast to specific detail type based on metric used
151
System.out.println("Detailed breakdown available");
152
}
153
154
// Access individual search hits with ratings
155
List<RatedSearchHit> hitsAndRatings = quality.getHitsAndRatings();
156
System.out.println("Evaluated " + hitsAndRatings.size() + " search hits");
157
}
158
```
159
160
### MetricDetail
161
162
Base class for metric-specific detailed breakdown information.
163
164
```java { .api }
165
public abstract class MetricDetail implements NamedWriteable, ToXContentFragment {
166
// Abstract methods implemented by metric-specific detail classes
167
public abstract XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException;
168
169
// Common serialization interface
170
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException;
171
}
172
```
173
174
**Metric-Specific Detail Classes:**
175
176
```java { .api }
177
// PrecisionAtK detailed results
178
public static class Detail extends MetricDetail {
179
public int getRelevantRetrieved();
180
public int getRetrieved();
181
}
182
183
// RecallAtK detailed results
184
public static class Detail extends MetricDetail {
185
public long getRelevantRetrieved();
186
public long getRelevant();
187
}
188
189
// MeanReciprocalRank detailed results
190
public static class Detail extends MetricDetail {
191
public int getFirstRelevantRank();
192
}
193
194
// DiscountedCumulativeGain detailed results
195
public static class Detail extends MetricDetail {
196
public double getDcg();
197
public double getIdealDcg();
198
public double getNdcg();
199
}
200
201
// ExpectedReciprocalRank detailed results
202
public static class Detail extends MetricDetail {
203
public double getErr();
204
}
205
```
206
207
## Plugin Infrastructure
208
209
### RankEvalPlugin
210
211
Main plugin class that registers the rank evaluation functionality with Elasticsearch.
212
213
```java { .api }
214
public class RankEvalPlugin extends Plugin implements ActionPlugin {
215
// Plugin lifecycle methods
216
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions();
217
public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
218
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings,
219
SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver,
220
Supplier<DiscoveryNodes> nodesInCluster);
221
222
// Serialization registry
223
public List<NamedWriteableRegistry.Entry> getNamedWriteables();
224
public List<Entry> getNamedXContent();
225
}
226
```
227
228
### RankEvalAction
229
230
Action type definition for rank evaluation operations.
231
232
```java { .api }
233
public class RankEvalAction extends ActionType<RankEvalResponse> {
234
// Singleton instance
235
public static final RankEvalAction INSTANCE = new RankEvalAction();
236
237
// Action name constant
238
public static final String NAME = "indices:data/read/rank_eval";
239
240
// Private constructor - use INSTANCE
241
private RankEvalAction();
242
}
243
```
244
245
### RestRankEvalAction
246
247
REST endpoint handler providing HTTP access to rank evaluation functionality.
248
249
```java { .api }
250
public class RestRankEvalAction extends BaseRestHandler {
251
// Supported HTTP methods and paths
252
public List<Route> routes();
253
public String getName();
254
255
// Request processing
256
public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException;
257
258
// Parameter parsing
259
protected static IndicesOptions parseIndicesOptions(RestRequest restRequest);
260
protected static SearchType parseSearchType(RestRequest restRequest);
261
}
262
```
263
264
**Supported Endpoints:**
265
- `GET /_rank_eval`
266
- `POST /_rank_eval`
267
- `GET /{index}/_rank_eval`
268
- `POST /{index}/_rank_eval`
269
270
### TransportRankEvalAction
271
272
Transport layer implementation handling distributed execution across cluster nodes.
273
274
```java { .api }
275
public class TransportRankEvalAction extends HandledTransportAction<RankEvalRequest, RankEvalResponse> {
276
// Constructor
277
public TransportRankEvalAction(TransportService transportService, ClusterService clusterService,
278
ThreadPool threadPool, ActionFilters actionFilters,
279
IndexNameExpressionResolver indexNameExpressionResolver, Client client);
280
281
// Core execution method
282
protected void doExecute(Task task, RankEvalRequest request, ActionListener<RankEvalResponse> listener);
283
}
284
```
285
286
## Content Providers and Parsers
287
288
### RankEvalNamedXContentProvider
289
290
Provides named XContent parsers for rank evaluation components, enabling JSON/XContent parsing.
291
292
```java { .api }
293
public class RankEvalNamedXContentProvider {
294
// Get list of named XContent parsers
295
public List<NamedXContentRegistry.Entry> getNamedXContentParsers();
296
}
297
```
298
299
## Configuration Examples
300
301
### Basic Configuration
302
303
```java
304
// Simple evaluation with default settings
305
PrecisionAtK metric = new PrecisionAtK();
306
RankEvalSpec spec = new RankEvalSpec(ratedRequests, metric);
307
RankEvalRequest request = new RankEvalRequest(spec, new String[]{"products"});
308
```
309
310
### Advanced Configuration
311
312
```java
313
// Custom metric configuration
314
DiscountedCumulativeGain ndcg = new DiscountedCumulativeGain(true, null, 20);
315
316
// Specification with templates and concurrency control
317
RankEvalSpec spec = new RankEvalSpec(ratedRequests, ndcg, templates);
318
spec.setMaxConcurrentSearches(5);
319
320
// Request with custom indices options
321
RankEvalRequest request = new RankEvalRequest(spec, new String[]{"index1", "index2"});
322
request.indicesOptions(IndicesOptions.strictExpandOpen());
323
request.searchType(SearchType.DFS_QUERY_THEN_FETCH);
324
```
325
326
### Template Configuration
327
328
```java
329
// Create query template
330
Script template = new Script(
331
ScriptType.INLINE,
332
"mustache",
333
"""
334
{
335
"query": {
336
"bool": {
337
"must": [
338
{"match": {"{{title_field}}": "{{search_term}}"}},
339
{"range": {"price": {"lte": {{max_price}}}}}
340
]
341
}
342
},
343
"sort": [{"_score": "desc"}, {"price": "asc"}]
344
}
345
""",
346
Collections.emptyMap()
347
);
348
349
// Wrap in ScriptWithId
350
ScriptWithId scriptWithId = new ScriptWithId("product_search", template);
351
352
// Create rated request using template
353
RatedRequest templateRequest = new RatedRequest(
354
"search_laptops",
355
"product_search",
356
Map.of(
357
"title_field", "title",
358
"search_term", "laptop",
359
"max_price", 2000
360
),
361
ratedDocs
362
);
363
364
// Include template in specification
365
RankEvalSpec spec = new RankEvalSpec(
366
Arrays.asList(templateRequest),
367
new PrecisionAtK(10, 2, false),
368
Arrays.asList(scriptWithId)
369
);
370
```
371
372
### Error Handling and Validation
373
374
```java
375
// Comprehensive error handling
376
try {
377
// Validate request before execution
378
ActionRequestValidationException validationException = request.validate();
379
if (validationException != null) {
380
System.err.println("Request validation failed: " + validationException.getMessage());
381
return;
382
}
383
384
// Execute request
385
RankEvalResponse response = client.execute(RankEvalAction.INSTANCE, request).get();
386
387
// Check for partial failures
388
Map<String, Exception> failures = response.getFailures();
389
if (!failures.isEmpty()) {
390
System.out.println("Some queries failed:");
391
failures.forEach((queryId, exception) ->
392
System.err.println(" " + queryId + ": " + exception.getMessage())
393
);
394
}
395
396
// Process successful results
397
double overallScore = response.getMetricScore();
398
Map<String, EvalQueryQuality> partialResults = response.getPartialResults();
399
400
System.out.println("Overall metric score: " + String.format("%.4f", overallScore));
401
System.out.println("Successful queries: " + partialResults.size());
402
403
} catch (ExecutionException e) {
404
if (e.getCause() instanceof ElasticsearchException) {
405
ElasticsearchException esException = (ElasticsearchException) e.getCause();
406
System.err.println("Elasticsearch error: " + esException.getMessage());
407
408
// Handle specific error types
409
if (esException instanceof IndexNotFoundException) {
410
System.err.println("One or more indices not found");
411
} else if (esException instanceof SearchPhaseExecutionException) {
412
System.err.println("Search phase execution failed");
413
}
414
}
415
} catch (InterruptedException e) {
416
Thread.currentThread().interrupt();
417
System.err.println("Request was interrupted");
418
}
419
```
420
421
### Performance Optimization
422
423
```java
424
// Optimize for large-scale evaluation
425
RankEvalSpec spec = new RankEvalSpec(ratedRequests, metric);
426
427
// Control concurrency to prevent resource exhaustion
428
spec.setMaxConcurrentSearches(3);
429
430
// Use appropriate search type for performance
431
request.searchType(SearchType.QUERY_THEN_FETCH);
432
433
// Configure indices options for efficiency
434
request.indicesOptions(IndicesOptions.lenientExpandOpen());
435
436
// For metrics that don't need full result sets, they may specify forced search size
437
OptionalInt forcedSize = metric.forcedSearchSize();
438
if (forcedSize.isPresent()) {
439
System.out.println("Metric requires search size: " + forcedSize.getAsInt());
440
}
441
```