org.elasticsearch.search.fetch.subphase.FetchDocValuesPhase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch subproject :server
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.search.fetch.subphase;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.index.mapper.DocValueFetcher;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.ValueFetcher;
import org.elasticsearch.search.fetch.FetchContext;
import org.elasticsearch.search.fetch.FetchSubPhase;
import org.elasticsearch.search.fetch.FetchSubPhaseProcessor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Fetch sub phase which pulls data from doc values.
*
* Specifying {@code "docvalue_fields": ["field1", "field2"]}
*/
public final class FetchDocValuesPhase implements FetchSubPhase {
private static final String USE_DEFAULT_FORMAT = "use_field_mapping";
private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(FetchDocValuesPhase.class);
@Override
public FetchSubPhaseProcessor getProcessor(FetchContext context) {
FetchDocValuesContext dvContext = context.docValuesContext();
if (dvContext == null) {
return null;
}
if (context.docValuesContext().fields().stream().map(f -> f.format).anyMatch(USE_DEFAULT_FORMAT::equals)) {
DEPRECATION_LOGGER.critical(
DeprecationCategory.API,
"explicit_default_format",
"["
+ USE_DEFAULT_FORMAT
+ "] is a special format that was only used to "
+ "ease the transition to 7.x. It has become the default and shouldn't be set explicitly anymore."
);
}
/*
* Its tempting to swap this to a `Map` but that'd break backwards
* compatibility because we support fetching the same field multiple
* times with different configuration. That isn't possible with a `Map`.
*/
List fields = new ArrayList<>();
for (FieldAndFormat fieldAndFormat : context.docValuesContext().fields()) {
MappedFieldType ft = context.getSearchExecutionContext().getFieldType(fieldAndFormat.field);
if (ft == null) {
continue;
}
String format = USE_DEFAULT_FORMAT.equals(fieldAndFormat.format) ? null : fieldAndFormat.format;
ValueFetcher fetcher = new DocValueFetcher(ft.docValueFormat(format, null), context.searchLookup().getForField(ft));
fields.add(new DocValueField(fieldAndFormat.field, fetcher));
}
return new FetchSubPhaseProcessor() {
@Override
public void setNextReader(LeafReaderContext readerContext) {
for (DocValueField f : fields) {
f.fetcher.setNextReader(readerContext);
}
}
@Override
public void process(HitContext hit) throws IOException {
for (DocValueField f : fields) {
DocumentField hitField = hit.hit().field(f.field);
if (hitField == null) {
hitField = new DocumentField(f.field, new ArrayList<>(2));
// even if we request a doc values of a meta-field (e.g. _routing),
// docValues fields will still be document fields, and put under "fields" section of a hit.
hit.hit().setDocumentField(f.field, hitField);
}
List