diff --git a/src/main/java/org/elasticsearch/index/fielddata/fieldcomparator/BytesRefOrdValComparator.java b/src/main/java/org/elasticsearch/index/fielddata/fieldcomparator/BytesRefOrdValComparator.java index 88c14112893..9a84bb82713 100644 --- a/src/main/java/org/elasticsearch/index/fielddata/fieldcomparator/BytesRefOrdValComparator.java +++ b/src/main/java/org/elasticsearch/index/fielddata/fieldcomparator/BytesRefOrdValComparator.java @@ -101,20 +101,14 @@ public final class BytesRefOrdValComparator extends NestedWrappableComparator> getForField(String fieldName) { - final IndexFieldData in = super.getForField(fieldName); + public static IndexFieldData> hideOrdinals(final IndexFieldData in) { return new IndexFieldData>() { @Override @@ -85,6 +82,12 @@ public class NoOrdinalsStringFieldDataTests extends PagedBytesStringFieldDataTes }; } + @SuppressWarnings("unchecked") + @Override + public IndexFieldData> getForField(String fieldName) { + return hideOrdinals(super.getForField(fieldName)); + } + @Test @Override public void testTermsEnum() throws Exception { diff --git a/src/test/java/org/elasticsearch/index/search/nested/NestedSortingTests.java b/src/test/java/org/elasticsearch/index/search/nested/NestedSortingTests.java index 3d56d6c3bc2..05a8d328d8f 100644 --- a/src/test/java/org/elasticsearch/index/search/nested/NestedSortingTests.java +++ b/src/test/java/org/elasticsearch/index/search/nested/NestedSortingTests.java @@ -30,17 +30,19 @@ import org.apache.lucene.search.join.FixedBitSetCachingWrapperFilter; import org.apache.lucene.search.join.ScoreMode; import org.apache.lucene.search.join.ToParentBlockJoinQuery; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.TestUtil; import org.elasticsearch.common.lucene.search.AndFilter; import org.elasticsearch.common.lucene.search.NotFilter; import org.elasticsearch.common.lucene.search.XFilteredQuery; import org.elasticsearch.common.settings.ImmutableSettings; -import org.elasticsearch.index.fielddata.AbstractFieldDataTests; -import org.elasticsearch.index.fielddata.FieldDataType; +import org.elasticsearch.index.fielddata.*; +import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource; import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource; -import org.elasticsearch.search.MultiValueMode; import org.elasticsearch.index.fielddata.plain.PagedBytesIndexFieldData; +import org.elasticsearch.search.MultiValueMode; import org.junit.Test; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -56,6 +58,61 @@ public class NestedSortingTests extends AbstractFieldDataTests { return new FieldDataType("string", ImmutableSettings.builder().put("format", "paged_bytes")); } + @Test + public void testDuel() throws Exception { + final int numDocs = scaledRandomIntBetween(100, 1000); + for (int i = 0; i < numDocs; ++i) { + final int numChildren = randomInt(2); + List docs = new ArrayList<>(numChildren + 1); + for (int j = 0; j < numChildren; ++j) { + Document doc = new Document(); + doc.add(new StringField("f", TestUtil.randomSimpleString(getRandom(), 2), Field.Store.NO)); + doc.add(new StringField("__type", "child", Field.Store.NO)); + docs.add(doc); + } + if (randomBoolean()) { + docs.add(new Document()); + } + Document parent = new Document(); + parent.add(new StringField("__type", "parent", Field.Store.NO)); + docs.add(parent); + writer.addDocuments(docs); + if (rarely()) { // we need to have a bit more segments than what RandomIndexWriter would do by default + DirectoryReader.open(writer, false).close(); + } + } + writer.commit(); + + MultiValueMode sortMode = randomFrom(Arrays.asList(MultiValueMode.MIN, MultiValueMode.MAX)); + IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(writer, false)); + PagedBytesIndexFieldData indexFieldData1 = getForField("f"); + IndexFieldData indexFieldData2 = NoOrdinalsStringFieldDataTests.hideOrdinals(indexFieldData1); + final String missingValue = randomBoolean() ? null : TestUtil.randomSimpleString(getRandom(), 2); + final int n = randomIntBetween(1, numDocs + 2); + final boolean reverse = randomBoolean(); + + final TopDocs topDocs1 = getTopDocs(searcher, indexFieldData1, missingValue, sortMode, n, reverse); + final TopDocs topDocs2 = getTopDocs(searcher, indexFieldData2, missingValue, sortMode, n, reverse); + for (int i = 0; i < topDocs1.scoreDocs.length; ++i) { + final FieldDoc fieldDoc1 = (FieldDoc) topDocs1.scoreDocs[i]; + final FieldDoc fieldDoc2 = (FieldDoc) topDocs2.scoreDocs[i]; + assertEquals(fieldDoc1.doc, fieldDoc2.doc); + assertArrayEquals(fieldDoc1.fields, fieldDoc2.fields); + } + + searcher.getIndexReader().close(); + } + + private TopDocs getTopDocs(IndexSearcher searcher, IndexFieldData indexFieldData, String missingValue, MultiValueMode sortMode, int n, boolean reverse) throws IOException { + Filter parentFilter = new TermFilter(new Term("__type", "parent")); + Filter childFilter = new TermFilter(new Term("__type", "child")); + XFieldComparatorSource innerSource = indexFieldData.comparatorSource(missingValue, sortMode); + NestedFieldComparatorSource nestedComparatorSource = new NestedFieldComparatorSource(sortMode, innerSource, parentFilter, childFilter); + Query query = new ConstantScoreQuery(parentFilter); + Sort sort = new Sort(new SortField("f", nestedComparatorSource, reverse)); + return searcher.search(query, n, sort); + } + @Test public void testNestedSorting() throws Exception { List docs = new ArrayList<>();