Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to skip using _ignored_source field for synthetic source #112963

Merged
merged 8 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.elasticsearch.index.engine.EngineConfig;
import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.FsDirectoryFactory;
Expand Down Expand Up @@ -183,6 +184,8 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
IndexSettings.PREFER_ILM_SETTING,
DataStreamFailureStoreDefinition.FAILURE_STORE_DEFINITION_VERSION_SETTING,
FieldMapper.SYNTHETIC_SOURCE_KEEP_INDEX_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING,

// validate that built-in similarities don't get redefined
Setting.groupSetting("index.similarity.", (s) -> {
Expand Down
26 changes: 26 additions & 0 deletions server/src/main/java/org/elasticsearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.ingest.IngestService;
Expand Down Expand Up @@ -778,6 +779,8 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
private volatile long mappingDepthLimit;
private volatile long mappingFieldNameLengthLimit;
private volatile long mappingDimensionFieldsLimit;
private volatile boolean skipIgnoredSourceWrite;
private volatile boolean skipIgnoredSourceRead;

/**
* The maximum number of refresh listeners allows on this shard.
Expand Down Expand Up @@ -936,6 +939,8 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
indexRouting = IndexRouting.fromIndexMetadata(indexMetadata);
sourceKeepMode = scopedSettings.get(Mapper.SYNTHETIC_SOURCE_KEEP_INDEX_SETTING);
es87TSDBCodecEnabled = scopedSettings.get(TIME_SERIES_ES87TSDB_CODEC_ENABLED_SETTING);
skipIgnoredSourceWrite = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING);
skipIgnoredSourceRead = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);

scopedSettings.addSettingsUpdateConsumer(
MergePolicyConfig.INDEX_COMPOUND_FORMAT_SETTING,
Expand Down Expand Up @@ -1018,6 +1023,11 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_DEPTH_LIMIT_SETTING, this::setMappingDepthLimit);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING, this::setMappingFieldNameLengthLimit);
scopedSettings.addSettingsUpdateConsumer(INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING, this::setMappingDimensionFieldsLimit);
scopedSettings.addSettingsUpdateConsumer(
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING,
this::setSkipIgnoredSourceWrite
);
scopedSettings.addSettingsUpdateConsumer(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING, this::setSkipIgnoredSourceRead);
}

private void setSearchIdleAfter(TimeValue searchIdleAfter) {
Expand Down Expand Up @@ -1594,6 +1604,22 @@ private void setMappingDimensionFieldsLimit(long value) {
this.mappingDimensionFieldsLimit = value;
}

public boolean getSkipIgnoredSourceWrite() {
return skipIgnoredSourceWrite;
}

private void setSkipIgnoredSourceWrite(boolean value) {
this.skipIgnoredSourceWrite = value;
}

public boolean getSkipIgnoredSourceRead() {
return skipIgnoredSourceRead;
}

private void setSkipIgnoredSourceRead(boolean value) {
this.skipIgnoredSourceRead = value;
}

/**
* The bounds for {@code @timestamp} on this index or
* {@code null} if there are no bounds.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ private GetResult innerGetFetch(
Map<String, DocumentField> metadataFields = null;
DocIdAndVersion docIdAndVersion = get.docIdAndVersion();
SourceLoader loader = forceSyntheticSource
? new SourceLoader.Synthetic(mappingLookup.getMapping()::syntheticFieldLoader, mapperMetrics.sourceFieldMetrics())
? new SourceLoader.Synthetic(
mappingLookup.getMapping()::syntheticFieldLoader,
indexSettings,
mapperMetrics.sourceFieldMetrics()
)
: mappingLookup.newSourceLoader(mapperMetrics.sourceFieldMetrics());
StoredFieldLoader storedFieldLoader = buildStoredFieldLoader(storedFields, fetchSourceContext, loader);
LeafStoredFieldLoader leafStoredFieldLoader = storedFieldLoader.getLoader(docIdAndVersion.reader.getContext(), null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ final boolean getClonedSource() {
}

public final boolean canAddIgnoredField() {
return mappingLookup.isSourceSynthetic() && clonedSource == false;
return mappingLookup.isSourceSynthetic() && clonedSource == false && indexSettings().getSkipIgnoredSourceWrite() == false;
}

Mapper.SourceKeepMode sourceKeepModeFromIndexSettings() {
Expand Down Expand Up @@ -367,7 +367,7 @@ public boolean isFieldAppliedFromTemplate(String name) {

public void markFieldAsCopyTo(String fieldName) {
copyToFields.add(fieldName);
if (mappingLookup.isSourceSynthetic()) {
if (mappingLookup.isSourceSynthetic() && indexSettings().getSkipIgnoredSourceWrite() == false) {
/*
Mark this field as containing copied data meaning it should not be present
in synthetic _source (to be consistent with stored _source).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import org.apache.lucene.document.StoredField;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.util.ByteUtils;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.core.Tuple;
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.query.SearchExecutionContext;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentType;
Expand All @@ -40,6 +42,7 @@
* if we can replace it for all use cases to avoid duplication, assuming that the storage tradeoff is favorable.
*/
public class IgnoredSourceFieldMapper extends MetadataFieldMapper {
private final IndexSettings indexSettings;

// This factor is used to combine two offsets within the same integer:
// - the offset of the end of the parent field within the field name (N / PARENT_OFFSET_IN_NAME_OFFSET)
Expand All @@ -49,12 +52,24 @@ public class IgnoredSourceFieldMapper extends MetadataFieldMapper {

public static final String NAME = "_ignored_source";

public static final IgnoredSourceFieldMapper INSTANCE = new IgnoredSourceFieldMapper();

public static final TypeParser PARSER = new FixedTypeParser(context -> INSTANCE);
public static final TypeParser PARSER = new FixedTypeParser(context -> new IgnoredSourceFieldMapper(context.getIndexSettings()));

static final NodeFeature TRACK_IGNORED_SOURCE = new NodeFeature("mapper.track_ignored_source");

public static final Setting<Boolean> SKIP_IGNORED_SOURCE_WRITE_SETTING = Setting.boolSetting(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add java doc on top of these public settings to explain what they do exactly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the java doc is now empty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fixed.

"index.mapping.synthetic_source.skip_ignored_source_write",
false,
Setting.Property.Dynamic,
Setting.Property.IndexScope
);

public static final Setting<Boolean> SKIP_IGNORED_SOURCE_READ_SETTING = Setting.boolSetting(
"index.mapping.synthetic_source.skip_ignored_source_read",
false,
Setting.Property.Dynamic,
Setting.Property.IndexScope
);

/*
* Container for the ignored field data:
* - the full name
Expand Down Expand Up @@ -108,8 +123,9 @@ public ValueFetcher valueFetcher(SearchExecutionContext context, String format)
}
}

private IgnoredSourceFieldMapper() {
private IgnoredSourceFieldMapper(IndexSettings indexSettings) {
super(IgnoredValuesFieldMapperType.INSTANCE);
this.indexSettings = indexSettings;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.fieldvisitor.LeafStoredFieldLoader;
Expand Down Expand Up @@ -48,11 +49,18 @@ public static class Builder extends ObjectMapper.Builder {
private Explicit<Boolean> includeInParent = Explicit.IMPLICIT_FALSE;
private final IndexVersion indexCreatedVersion;
private final Function<Query, BitSetProducer> bitSetProducer;
private final IndexSettings indexSettings;

public Builder(String name, IndexVersion indexCreatedVersion, Function<Query, BitSetProducer> bitSetProducer) {
public Builder(
String name,
IndexVersion indexCreatedVersion,
Function<Query, BitSetProducer> bitSetProducer,
IndexSettings indexSettings
) {
super(name, Optional.empty());
this.indexCreatedVersion = indexCreatedVersion;
this.bitSetProducer = bitSetProducer;
this.indexSettings = indexSettings;
}

Builder includeInRoot(boolean includeInRoot) {
Expand Down Expand Up @@ -113,7 +121,8 @@ public NestedObjectMapper build(MapperBuilderContext context) {
parentTypeFilter,
nestedTypePath,
nestedTypeFilter,
bitSetProducer
bitSetProducer,
indexSettings
);
}
}
Expand All @@ -128,7 +137,8 @@ public Mapper.Builder parse(String name, Map<String, Object> node, MappingParser
NestedObjectMapper.Builder builder = new NestedObjectMapper.Builder(
name,
parserContext.indexVersionCreated(),
parserContext::bitSetProducer
parserContext::bitSetProducer,
parserContext.getIndexSettings()
);
parseNested(name, node, builder);
parseObjectFields(node, parserContext, builder);
Expand Down Expand Up @@ -195,6 +205,7 @@ public MapperBuilderContext createChildContext(String name, Dynamic dynamic) {
private final Query nestedTypeFilter;
// Function to create a bitset for identifying parent documents
private final Function<Query, BitSetProducer> bitsetProducer;
private final IndexSettings indexSettings;

NestedObjectMapper(
String name,
Expand All @@ -208,7 +219,8 @@ public MapperBuilderContext createChildContext(String name, Dynamic dynamic) {
Query parentTypeFilter,
String nestedTypePath,
Query nestedTypeFilter,
Function<Query, BitSetProducer> bitsetProducer
Function<Query, BitSetProducer> bitsetProducer,
IndexSettings indexSettings
) {
super(name, fullPath, enabled, Optional.empty(), storeArraySource, dynamic, mappers);
this.parentTypeFilter = parentTypeFilter;
Expand All @@ -217,6 +229,7 @@ public MapperBuilderContext createChildContext(String name, Dynamic dynamic) {
this.includeInParent = includeInParent;
this.includeInRoot = includeInRoot;
this.bitsetProducer = bitsetProducer;
this.indexSettings = indexSettings;
}

public Query parentTypeFilter() {
Expand Down Expand Up @@ -254,7 +267,7 @@ public Map<String, Mapper> getChildren() {

@Override
public ObjectMapper.Builder newBuilder(IndexVersion indexVersionCreated) {
NestedObjectMapper.Builder builder = new NestedObjectMapper.Builder(leafName(), indexVersionCreated, bitsetProducer);
NestedObjectMapper.Builder builder = new NestedObjectMapper.Builder(leafName(), indexVersionCreated, bitsetProducer, indexSettings);
builder.enabled = enabled;
builder.dynamic = dynamic;
builder.includeInRoot = includeInRoot;
Expand All @@ -276,7 +289,8 @@ NestedObjectMapper withoutMappers() {
parentTypeFilter,
nestedTypePath,
nestedTypeFilter,
bitsetProducer
bitsetProducer,
indexSettings
);
}

Expand Down Expand Up @@ -351,7 +365,8 @@ public ObjectMapper merge(Mapper mergeWith, MapperMergeContext parentMergeContex
parentTypeFilter,
nestedTypePath,
nestedTypeFilter,
bitsetProducer
bitsetProducer,
indexSettings
);
}

Expand Down Expand Up @@ -383,7 +398,11 @@ public SourceLoader.SyntheticFieldLoader syntheticFieldLoader() {
return SourceLoader.SyntheticFieldLoader.NOTHING;
}

SourceLoader sourceLoader = new SourceLoader.Synthetic(() -> super.syntheticFieldLoader(mappers.values().stream(), true), NOOP);
SourceLoader sourceLoader = new SourceLoader.Synthetic(
() -> super.syntheticFieldLoader(mappers.values().stream(), true),
indexSettings,
NOOP
);
var storedFieldLoader = org.elasticsearch.index.fieldvisitor.StoredFieldLoader.create(false, sourceLoader.requiredStoredFields());
return new NestedSyntheticFieldLoader(
storedFieldLoader,
Expand Down
Loading