-
Notifications
You must be signed in to change notification settings - Fork 25.5k
Fixed geo point block loader slowness #136147
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
base: main
Are you sure you want to change the base?
Conversation
Hi @Kubik42, I've created a changelog YAML for you. |
e7afa0b
to
1f168f2
Compare
server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java
Show resolved
Hide resolved
The reason for failing tests is here. Whenever there is no Perhaps the bigger problem here is that |
In my rabbit hole of understanding how BlockLoaders work, I found a somewhat of a bug thats in main. When a For example, the following command fails:
with:
Based on what I've read in the code, this precision loss is expected. That being said, its not documented publicly. |
There is also a problem with using When block loading, I get the error: My guess is that it has something to do with the geo_point being stored as a String, rather than being converted to WKT first. That said, even when I used For now, I've just followed what we do in GeoShapeWithDocValuesFieldMapper and changed the block loader to This needs further discussion. |
1f168f2
to
b586f4c
Compare
server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java
Outdated
Show resolved
Hide resolved
I did a little more investigating and found that the reason we end up with This got me thinking, why are we setting the preference to
However, doing so causes some type inequality exceptions. Nhat pointed out this code, which suggests that doc_values shouldn't be always be used. However, that conflicts with the definition of |
e9ba832
to
7176d9e
Compare
7176d9e
to
8573b2f
Compare
adc51f9
to
5cedfba
Compare
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.
I left a few comments.
server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java
Show resolved
Hide resolved
* This implies that we need to load the value from _source. This however is very slow, especially when synthetic source is enabled. | ||
* We're better off reading from doc_values and converting to BytesRef to satisfy the checker. This is what this block loader is for. | ||
*/ | ||
static class BytesRefFromLongsBlockLoader extends BlockDocValuesReader.DocValuesBlockLoader { |
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.
seal classes?
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.
did you mean final
? sealed
doesn't work on BytesRefFromLongsBlockLoader
since it has no subclasses
server/src/main/java/org/elasticsearch/index/mapper/IndexType.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
public TestBlock build() { |
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.
why can this be removed now?
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.
I wasn't actually sure about this, but it was causing issues for my tests. When the block loader was reading values, it always ended up with two values: one containing the point and one containing null. I checked and this is the same behavior as the current BlockDocValuesReader.LongsBlockLoader
. However, because expectedCount
was hard coded, I was getting the error something along the lines of "expected 1 but got 2".
There are 12 classes in this file and none of them hard code expectedCount
. And this one has no explanation as to why. After digging around, it seems as if this class was coded explicitly to work with BlockDocValuesReader.Ordinals.readSingleDoc()
. So I figured it can be changed to accommodate others.
The code on lines 69-81 is deleted because it works with the assumption that there is only one value. Which is no longer the case.
That being said... it seems as though KeywordFieldBlockLoaderTests
actually depends on the original behavior with expectedCount = 1
.
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.
tbh I don't know what to do with this code. Removing it makes the most sense to me and its what makes the geo point block loader tests pass. However, it causes failures in keyword and version string block loader tests:
./gradlew ":x-pack:plugin:mapper-version:test" --tests "org.elasticsearch.xpack.versionfield.VersionStringFieldBlockLoaderTests.testBlockLoaderForFieldInObject {preference=Params[syntheticSource=true, preference=NONE]}" -Dtests.seed=5705FB7B03C2B578 -Dtests.locale=lg -Dtests.timezone=America/Tegucigalpa -Druntime.java=25
2> java.lang.AssertionError:
Expected: a collection with size <9>
but: collection size was <1>
at __randomizedtesting.SeedInfo.seed([5705FB7B03C2B578:F9E93A4005FCC128]:0)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
at org.elasticsearch.test.ESTestCase.assertThat(ESTestCase.java:2722)
at org.elasticsearch.index.mapper.TestBlock$Builder.build(TestBlock.java:495)
at org.elasticsearch.index.mapper.TestBlock$Builder.build(TestBlock.java:456)
at org.elasticsearch.index.mapper.BlockDocValuesReader$Ordinals.readSingleDoc(BlockDocValuesReader.java:874)
at org.elasticsearch.index.mapper.BlockDocValuesReader$Ordinals.read(BlockDocValuesReader.java:826)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.load(BlockLoaderTestRunner.java:117)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.setupAndInvokeBlockLoader(BlockLoaderTestRunner.java:84)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.runTest(BlockLoaderTestRunner.java:55)
at org.elasticsearch.index.mapper.BlockLoaderTestCase.testBlockLoaderForFieldInObject(BlockLoaderTestCase.java:146)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at com.carrotsearch.randomizedtesting.RandomizedRunner.invoke(RandomizedRunner.java:1763)
at com.carrotsearch.randomizedtesting.RandomizedRunner$8.evaluate(RandomizedRunner.java:946)
at com.carrotsearch.randomizedtesting.RandomizedRunner$9.evaluate(RandomizedRunner.java:982)
at com.carrotsearch.randomizedtesting.RandomizedRunner$10.evaluate(RandomizedRunner.java:996)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.apache.lucene.tests.util.TestRuleSetupTeardownChained$1.evaluate(TestRuleSetupTeardownChained.java:48)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at org.apache.lucene.tests.util.TestRuleThreadAndTestName$1.evaluate(TestRuleThreadAndTestName.java:45)
at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:390)
at com.carrotsearch.randomizedtesting.ThreadLeakControl.forkTimeoutingTask(ThreadLeakControl.java:843)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$3.evaluate(ThreadLeakControl.java:490)
at com.carrotsearch.randomizedtesting.RandomizedRunner.runSingleTest(RandomizedRunner.java:955)
at com.carrotsearch.randomizedtesting.RandomizedRunner$5.evaluate(RandomizedRunner.java:840)
at com.carrotsearch.randomizedtesting.RandomizedRunner$6.evaluate(RandomizedRunner.java:891)
at com.carrotsearch.randomizedtesting.RandomizedRunner$7.evaluate(RandomizedRunner.java:902)
at org.elasticsearch.entitlement.bootstrap.TestEntitlementsRule$1.evaluate(TestEntitlementsRule.java:77)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.apache.lucene.tests.util.TestRuleStoreClassName$1.evaluate(TestRuleStoreClassName.java:38)
at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.apache.lucene.tests.util.TestRuleAssertionsRequired$1.evaluate(TestRuleAssertionsRequired.java:53)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
at org.apache.lucene.tests.util.TestRuleIgnoreTestSuites$1.evaluate(TestRuleIgnoreTestSuites.java:47)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:390)
at com.carrotsearch.randomizedtesting.ThreadLeakControl.lambda$forkTimeoutingTask$0(ThreadLeakControl.java:850)
at java.base/java.lang.Thread.run(Thread.java:1474)
./gradlew ":server:test" --tests "org.elasticsearch.index.mapper.blockloader.KeywordFieldBlockLoaderTests.testBlockLoaderForFieldInObject {preference=Params[syntheticSource=false, preference=DOC_VALUES]}" -Dtests.seed=57E4325AA9984681 -Dtests.locale=fr-BJ -Dtests.timezone=Africa/Gaborone -Druntime.java=25
2> java.lang.AssertionError:
Expected: a collection with size <2>
but: collection size was <1>
at __randomizedtesting.SeedInfo.seed([57E4325AA9984681:F908F361AFA632D1]:0)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
at org.elasticsearch.test.ESTestCase.assertThat(ESTestCase.java:2722)
at org.elasticsearch.index.mapper.TestBlock$Builder.build(TestBlock.java:495)
at org.elasticsearch.index.mapper.TestBlock$Builder.build(TestBlock.java:456)
at org.elasticsearch.index.mapper.BlockDocValuesReader$Ordinals.readSingleDoc(BlockDocValuesReader.java:874)
at org.elasticsearch.index.mapper.BlockDocValuesReader$Ordinals.read(BlockDocValuesReader.java:826)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.load(BlockLoaderTestRunner.java:117)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.setupAndInvokeBlockLoader(BlockLoaderTestRunner.java:84)
at org.elasticsearch.index.mapper.BlockLoaderTestRunner.runTest(BlockLoaderTestRunner.java:55)
at org.elasticsearch.index.mapper.BlockLoaderTestCase.testBlockLoaderForFieldInObject(BlockLoaderTestCase.java:146)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at com.carrotsearch.randomizedtesting.RandomizedRunner.invoke(RandomizedRunner.java:1763)
at com.carrotsearch.randomizedtesting.RandomizedRunner$8.evaluate(RandomizedRunner.java:946)
at com.carrotsearch.randomizedtesting.RandomizedRunner$9.evaluate(RandomizedRunner.java:982)
at com.carrotsearch.randomizedtesting.RandomizedRunner$10.evaluate(RandomizedRunner.java:996)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.apache.lucene.tests.util.TestRuleSetupTeardownChained$1.evaluate(TestRuleSetupTeardownChained.java:48)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at org.apache.lucene.tests.util.TestRuleThreadAndTestName$1.evaluate(TestRuleThreadAndTestName.java:45)
at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:390)
at com.carrotsearch.randomizedtesting.ThreadLeakControl.forkTimeoutingTask(ThreadLeakControl.java:843)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$3.evaluate(ThreadLeakControl.java:490)
at com.carrotsearch.randomizedtesting.RandomizedRunner.runSingleTest(RandomizedRunner.java:955)
at com.carrotsearch.randomizedtesting.RandomizedRunner$5.evaluate(RandomizedRunner.java:840)
at com.carrotsearch.randomizedtesting.RandomizedRunner$6.evaluate(RandomizedRunner.java:891)
at com.carrotsearch.randomizedtesting.RandomizedRunner$7.evaluate(RandomizedRunner.java:902)
at org.elasticsearch.entitlement.bootstrap.TestEntitlementsRule$1.evaluate(TestEntitlementsRule.java:77)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.apache.lucene.tests.util.TestRuleStoreClassName$1.evaluate(TestRuleStoreClassName.java:38)
at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
at com.carrotsearch.randomizedtesting.rules.NoShadowingOrOverridesOnMethodsRule$1.evaluate(NoShadowingOrOverridesOnMethodsRule.java:40)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at org.apache.lucene.tests.util.TestRuleAssertionsRequired$1.evaluate(TestRuleAssertionsRequired.java:53)
at org.apache.lucene.tests.util.AbstractBeforeAfterRule$1.evaluate(AbstractBeforeAfterRule.java:43)
at org.apache.lucene.tests.util.TestRuleMarkFailure$1.evaluate(TestRuleMarkFailure.java:44)
at org.apache.lucene.tests.util.TestRuleIgnoreAfterMaxFailures$1.evaluate(TestRuleIgnoreAfterMaxFailures.java:60)
at org.apache.lucene.tests.util.TestRuleIgnoreTestSuites$1.evaluate(TestRuleIgnoreTestSuites.java:47)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at com.carrotsearch.randomizedtesting.rules.StatementAdapter.evaluate(StatementAdapter.java:36)
at com.carrotsearch.randomizedtesting.ThreadLeakControl$StatementRunner.run(ThreadLeakControl.java:390)
at com.carrotsearch.randomizedtesting.ThreadLeakControl.lambda$forkTimeoutingTask$0(ThreadLeakControl.java:850)
at java.base/java.lang.Thread.run(Thread.java:1474)
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.
Theres a knowledge gap I need filled :)
|
||
// then | ||
// verify that we use the correct block value reader | ||
assertThat(loader, instanceOf(BlockSourceReader.GeometriesBlockLoader.class)); |
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.
Maybe I misunderstand this, but stored field and stored preference is handled yet in the block loader method?
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.
I didn't change how stored fields and stored preference is handled, only how doc_values + synthetic source are handled.
That being said, in the draft version of this PR, I did have some code to handle stored fields. However, I've since removed it since it required extra effort to get working. If you think its important to handle that case, then I'll add it back in.
c1efcb3
to
a024bae
Compare
a024bae
to
212fe97
Compare
9f1057d
to
c24d31e
Compare
This addresses #135891
TODO: write up explanation of what went wrong and his this PR fixes it