-
Notifications
You must be signed in to change notification settings - Fork 25.7k
Store ignored source in unique stored fields per entry #132142
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
Merged
jordan-powers
merged 33 commits into
elastic:main
from
jordan-powers:ignored-source-unique-fields-2
Aug 14, 2025
Merged
Changes from 21 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
9c68921
Store _ignored_source in different fields per entry
jordan-powers 09ecbb8
Coalesce multiple ignored source entries into single field
jordan-powers f8260c2
Add WildcardFieldMaskingReader
jordan-powers ab1550e
Update FieldSubsetReader for new _ignored_source fields
jordan-powers a11d2ac
Update invalid assertion in PreloadedFieldLookupProvider
jordan-powers da7c4f1
Only store fieldName once
jordan-powers 3e04818
Remove MappedNameValueWithFilter
jordan-powers 5a44487
Fix IgnoredSourceFieldMapperTests
jordan-powers 38e5420
Add NOOP IgnoredFieldsLoader
jordan-powers ae1c258
Fix more tests
jordan-powers 6f75669
Fix FieldSubsetReaderTests
jordan-powers 3cd0415
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers d042cab
Get _ignored_source from stored_fields request
jordan-powers d5e9e86
Update binary format in 20_ignored_source yaml test
jordan-powers a5838d9
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers 50e6c57
Use IgnoredFieldsLoader in FallbackSyntheticSourceBlockLoader
jordan-powers 01a46f0
Rename IgnoredFieldsLoader to IgnoredSourceFormat
jordan-powers 5a80a3e
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers 5f52d64
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers 2869608
Move writeIgnoredFields into IgnoredSourceFormat
jordan-powers da674b9
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers c57d2eb
Review nits
jordan-powers c2dec2f
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers fcaf270
Switch UnsupportedOperationException to assert false
jordan-powers 1741541
Add feature flag
jordan-powers 3181236
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers bdd031a
Test with random index version
jordan-powers 5edc55b
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers c392437
Fix release tests
jordan-powers 6d6b9f0
Fix release tests
jordan-powers 64d5f6b
Revert "Fix release tests"
jordan-powers df518aa
Fix release tests
jordan-powers 7f502a2
Merge remote-tracking branch 'upstream/main' into ignored-source-uniq…
jordan-powers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,13 +17,13 @@ | |
|
|
||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Optional; | ||
| import java.util.Set; | ||
| import java.util.Stack; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| /** | ||
| * Block loader for fields that use fallback synthetic source implementation. | ||
|
|
@@ -39,10 +39,19 @@ | |
| public abstract class FallbackSyntheticSourceBlockLoader implements BlockLoader { | ||
| private final Reader<?> reader; | ||
| private final String fieldName; | ||
|
|
||
| protected FallbackSyntheticSourceBlockLoader(Reader<?> reader, String fieldName) { | ||
| private final Set<String> fieldPaths; | ||
| private final IgnoredSourceFieldMapper.IgnoredSourceFormat ignoredSourceFormat; | ||
|
|
||
| protected FallbackSyntheticSourceBlockLoader( | ||
| Reader<?> reader, | ||
| String fieldName, | ||
| IgnoredSourceFieldMapper.IgnoredSourceFormat ignoredSourceFormat | ||
| ) { | ||
| assert ignoredSourceFormat != IgnoredSourceFieldMapper.IgnoredSourceFormat.NO_IGNORED_SOURCE; | ||
| this.reader = reader; | ||
| this.fieldName = fieldName; | ||
| this.ignoredSourceFormat = ignoredSourceFormat; | ||
| this.fieldPaths = splitIntoFieldPaths(fieldName); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, now we do this once per field and shard instead of once per field and segment. |
||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -52,12 +61,19 @@ public ColumnAtATimeReader columnAtATimeReader(LeafReaderContext context) throws | |
|
|
||
| @Override | ||
| public RowStrideReader rowStrideReader(LeafReaderContext context) throws IOException { | ||
| return new IgnoredSourceRowStrideReader<>(fieldName, reader); | ||
| return new IgnoredSourceRowStrideReader<>(fieldName, fieldPaths, reader, ignoredSourceFormat); | ||
| } | ||
|
|
||
| @Override | ||
| public StoredFieldsSpec rowStrideStoredFieldSpec() { | ||
| return new StoredFieldsSpec(false, false, Set.of(IgnoredSourceFieldMapper.NAME)); | ||
| Set<String> ignoredFieldNames; | ||
| if (ignoredSourceFormat == IgnoredSourceFieldMapper.IgnoredSourceFormat.PER_FIELD_IGNORED_SOURCE) { | ||
| ignoredFieldNames = fieldPaths.stream().map(IgnoredSourceFieldMapper::ignoredFieldName).collect(Collectors.toSet()); | ||
| } else { | ||
| ignoredFieldNames = Set.of(IgnoredSourceFieldMapper.NAME); | ||
| } | ||
|
|
||
| return new StoredFieldsSpec(false, false, ignoredFieldNames); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -70,49 +86,51 @@ public SortedSetDocValues ordinals(LeafReaderContext context) throws IOException | |
| throw new UnsupportedOperationException(); | ||
| } | ||
|
|
||
| public static Set<String> splitIntoFieldPaths(String fieldName) { | ||
| var paths = new HashSet<String>(); | ||
| paths.add("_doc"); | ||
| var current = new StringBuilder(); | ||
| for (var part : fieldName.split("\\.")) { | ||
| if (current.isEmpty() == false) { | ||
| current.append('.'); | ||
| } | ||
| current.append(part); | ||
| paths.add(current.toString()); | ||
| } | ||
| return paths; | ||
| } | ||
|
|
||
| private static class IgnoredSourceRowStrideReader<T> implements RowStrideReader { | ||
| // Contains name of the field and all its parents | ||
|
||
| private final Set<String> fieldNames; | ||
| private final String fieldName; | ||
| private final Set<String> fieldPaths; | ||
| private final Reader<T> reader; | ||
|
|
||
| IgnoredSourceRowStrideReader(String fieldName, Reader<T> reader) { | ||
| private final IgnoredSourceFieldMapper.IgnoredSourceFormat ignoredSourceFormat; | ||
|
|
||
| IgnoredSourceRowStrideReader( | ||
| String fieldName, | ||
| Set<String> fieldPaths, | ||
| Reader<T> reader, | ||
| IgnoredSourceFieldMapper.IgnoredSourceFormat ignoredSourceFormat | ||
| ) { | ||
| this.fieldName = fieldName; | ||
| this.fieldPaths = fieldPaths; | ||
| this.reader = reader; | ||
| this.fieldNames = new HashSet<>() { | ||
| { | ||
| add("_doc"); | ||
| } | ||
| }; | ||
|
|
||
| var current = new StringBuilder(); | ||
| for (String part : fieldName.split("\\.")) { | ||
| if (current.isEmpty() == false) { | ||
| current.append('.'); | ||
| } | ||
| current.append(part); | ||
| fieldNames.add(current.toString()); | ||
| } | ||
|
|
||
| this.ignoredSourceFormat = ignoredSourceFormat; | ||
| } | ||
|
|
||
| @Override | ||
| public void read(int docId, StoredFields storedFields, Builder builder) throws IOException { | ||
| var ignoredSource = storedFields.storedFields().get(IgnoredSourceFieldMapper.NAME); | ||
| if (ignoredSource == null) { | ||
| Map<String, List<IgnoredSourceFieldMapper.NameValue>> valuesForFieldAndParents = ignoredSourceFormat.loadSingleIgnoredField( | ||
| fieldPaths, | ||
| storedFields.storedFields() | ||
| ); | ||
|
|
||
| if (valuesForFieldAndParents.isEmpty()) { | ||
| builder.appendNull(); | ||
| return; | ||
| } | ||
|
|
||
| Map<String, List<IgnoredSourceFieldMapper.NameValue>> valuesForFieldAndParents = new HashMap<>(); | ||
|
|
||
| for (Object value : ignoredSource) { | ||
| IgnoredSourceFieldMapper.NameValue nameValue = IgnoredSourceFieldMapper.decode(value); | ||
| if (fieldNames.contains(nameValue.name())) { | ||
| valuesForFieldAndParents.computeIfAbsent(nameValue.name(), k -> new ArrayList<>()).add(nameValue); | ||
| } | ||
| } | ||
|
|
||
| // TODO figure out how to handle XContentDataHelper#voidValue() | ||
|
|
||
| var blockValues = new ArrayList<T>(); | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this per field ignored source this can be improved in a followup.