Search in sources :

Example 1 with BytesRefFieldComparatorSource

use of org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource in project OpenSearch by opensearch-project.

the class SortedSetOrdinalsIndexFieldData method sortField.

@Override
public SortField sortField(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
    XFieldComparatorSource source = new BytesRefFieldComparatorSource(this, missingValue, sortMode, nested);
    /**
     * Check if we can use a simple {@link SortedSetSortField} compatible with index sorting and
     * returns a custom sort field otherwise.
     */
    if (nested != null || (sortMode != MultiValueMode.MAX && sortMode != MultiValueMode.MIN) || (source.sortMissingLast(missingValue) == false && source.sortMissingFirst(missingValue) == false)) {
        return new SortField(getFieldName(), source, reverse);
    }
    SortField sortField = new SortedSetSortField(getFieldName(), reverse, sortMode == MultiValueMode.MAX ? SortedSetSelector.Type.MAX : SortedSetSelector.Type.MIN);
    sortField.setMissingValue(source.sortMissingLast(missingValue) ^ reverse ? SortedSetSortField.STRING_LAST : SortedSetSortField.STRING_FIRST);
    return sortField;
}
Also used : SortedSetSortField(org.apache.lucene.search.SortedSetSortField) BytesRefFieldComparatorSource(org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource) SortedSetSortField(org.apache.lucene.search.SortedSetSortField) SortField(org.apache.lucene.search.SortField)

Example 2 with BytesRefFieldComparatorSource

use of org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource in project OpenSearch by opensearch-project.

the class NestedSortingTests method testNestedSorting.

public void testNestedSorting() throws Exception {
    List<Document> docs = new ArrayList<>();
    Document document = new Document();
    document.add(new StringField("field2", "a", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "b", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "c", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "a", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    writer.commit();
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "c", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "d", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "e", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "b", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "e", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "f", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "g", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "c", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "g", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "h", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "i", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "d", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    writer.commit();
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "i", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "j", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "k", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "f", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "k", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "l", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "m", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "g", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    // This doc will not be included, because it doesn't have nested docs
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "h", Field.Store.NO));
    writer.addDocument(document);
    docs.clear();
    document = new Document();
    document.add(new StringField("field2", "m", Field.Store.NO));
    document.add(new StringField("filter_1", "T", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "n", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("field2", "o", Field.Store.NO));
    document.add(new StringField("filter_1", "F", Field.Store.NO));
    docs.add(document);
    document = new Document();
    document.add(new StringField("__type", "parent", Field.Store.NO));
    document.add(new StringField("field1", "i", Field.Store.NO));
    docs.add(document);
    writer.addDocuments(docs);
    writer.commit();
    // Some garbage docs, just to check if the NestedFieldComparator can deal with this.
    document = new Document();
    document.add(new StringField("fieldXXX", "x", Field.Store.NO));
    writer.addDocument(document);
    document = new Document();
    document.add(new StringField("fieldXXX", "x", Field.Store.NO));
    writer.addDocument(document);
    document = new Document();
    document.add(new StringField("fieldXXX", "x", Field.Store.NO));
    writer.addDocument(document);
    MultiValueMode sortMode = MultiValueMode.MIN;
    DirectoryReader reader = DirectoryReader.open(writer);
    reader = OpenSearchDirectoryReader.wrap(reader, new ShardId(indexService.index(), 0));
    IndexSearcher searcher = new IndexSearcher(reader);
    PagedBytesIndexFieldData indexFieldData = getForField("field2");
    Query parentFilter = new TermQuery(new Term("__type", "parent"));
    Query childFilter = Queries.not(parentFilter);
    BytesRefFieldComparatorSource nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(searcher, parentFilter, childFilter));
    ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new ConstantScoreQuery(childFilter), new QueryBitSetProducer(parentFilter), ScoreMode.None);
    Sort sort = new Sort(new SortField("field2", nestedComparatorSource));
    TopFieldDocs topDocs = searcher.search(query, 5, sort);
    assertThat(topDocs.totalHits.value, equalTo(7L));
    assertThat(topDocs.scoreDocs.length, equalTo(5));
    assertThat(topDocs.scoreDocs[0].doc, equalTo(3));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).utf8ToString(), equalTo("a"));
    assertThat(topDocs.scoreDocs[1].doc, equalTo(7));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).utf8ToString(), equalTo("c"));
    assertThat(topDocs.scoreDocs[2].doc, equalTo(11));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).utf8ToString(), equalTo("e"));
    assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).utf8ToString(), equalTo("g"));
    assertThat(topDocs.scoreDocs[4].doc, equalTo(19));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).utf8ToString(), equalTo("i"));
    sortMode = MultiValueMode.MAX;
    nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(searcher, parentFilter, childFilter));
    sort = new Sort(new SortField("field2", nestedComparatorSource, true));
    topDocs = searcher.search(query, 5, sort);
    assertThat(topDocs.totalHits.value, equalTo(7L));
    assertThat(topDocs.scoreDocs.length, equalTo(5));
    assertThat(topDocs.scoreDocs[0].doc, equalTo(28));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).utf8ToString(), equalTo("o"));
    assertThat(topDocs.scoreDocs[1].doc, equalTo(23));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).utf8ToString(), equalTo("m"));
    assertThat(topDocs.scoreDocs[2].doc, equalTo(19));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).utf8ToString(), equalTo("k"));
    assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).utf8ToString(), equalTo("i"));
    assertThat(topDocs.scoreDocs[4].doc, equalTo(11));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).utf8ToString(), equalTo("g"));
    BooleanQuery.Builder bq = new BooleanQuery.Builder();
    bq.add(parentFilter, Occur.MUST_NOT);
    bq.add(new TermQuery(new Term("filter_1", "T")), Occur.MUST);
    childFilter = bq.build();
    nestedComparatorSource = new BytesRefFieldComparatorSource(indexFieldData, null, sortMode, createNested(searcher, parentFilter, childFilter));
    query = new ToParentBlockJoinQuery(new ConstantScoreQuery(childFilter), new QueryBitSetProducer(parentFilter), ScoreMode.None);
    sort = new Sort(new SortField("field2", nestedComparatorSource, true));
    topDocs = searcher.search(query, 5, sort);
    assertThat(topDocs.totalHits.value, equalTo(6L));
    assertThat(topDocs.scoreDocs.length, equalTo(5));
    assertThat(topDocs.scoreDocs[0].doc, equalTo(23));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[0]).fields[0]).utf8ToString(), equalTo("m"));
    assertThat(topDocs.scoreDocs[1].doc, equalTo(28));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[1]).fields[0]).utf8ToString(), equalTo("m"));
    assertThat(topDocs.scoreDocs[2].doc, equalTo(11));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[2]).fields[0]).utf8ToString(), equalTo("g"));
    assertThat(topDocs.scoreDocs[3].doc, equalTo(15));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[3]).fields[0]).utf8ToString(), equalTo("g"));
    assertThat(topDocs.scoreDocs[4].doc, equalTo(7));
    assertThat(((BytesRef) ((FieldDoc) topDocs.scoreDocs[4]).fields[0]).utf8ToString(), equalTo("e"));
    searcher.getIndexReader().close();
}
Also used : IndexSearcher(org.apache.lucene.search.IndexSearcher) PagedBytesIndexFieldData(org.opensearch.index.fielddata.plain.PagedBytesIndexFieldData) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) Query(org.apache.lucene.search.Query) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) TermQuery(org.apache.lucene.search.TermQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) ToParentBlockJoinQuery(org.apache.lucene.search.join.ToParentBlockJoinQuery) DirectoryReader(org.apache.lucene.index.DirectoryReader) OpenSearchDirectoryReader(org.opensearch.common.lucene.index.OpenSearchDirectoryReader) FieldSortBuilder(org.opensearch.search.sort.FieldSortBuilder) NestedQueryBuilder(org.opensearch.index.query.NestedQueryBuilder) QueryBuilder(org.opensearch.index.query.QueryBuilder) RangeQueryBuilder(org.opensearch.index.query.RangeQueryBuilder) NestedSortBuilder(org.opensearch.search.sort.NestedSortBuilder) TermQueryBuilder(org.opensearch.index.query.TermQueryBuilder) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder) MatchAllQueryBuilder(org.opensearch.index.query.MatchAllQueryBuilder) ArrayList(java.util.ArrayList) BytesRefFieldComparatorSource(org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource) TopFieldDocs(org.apache.lucene.search.TopFieldDocs) SortField(org.apache.lucene.search.SortField) Term(org.apache.lucene.index.Term) Document(org.apache.lucene.document.Document) MultiValueMode(org.opensearch.search.MultiValueMode) ShardId(org.opensearch.index.shard.ShardId) ToParentBlockJoinQuery(org.apache.lucene.search.join.ToParentBlockJoinQuery) StringField(org.apache.lucene.document.StringField) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) QueryBitSetProducer(org.apache.lucene.search.join.QueryBitSetProducer) Sort(org.apache.lucene.search.Sort)

Example 3 with BytesRefFieldComparatorSource

use of org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource in project OpenSearch by opensearch-project.

the class ScriptSortBuilder method fieldComparatorSource.

private IndexFieldData.XFieldComparatorSource fieldComparatorSource(QueryShardContext context) throws IOException {
    MultiValueMode valueMode = null;
    if (sortMode != null) {
        valueMode = MultiValueMode.fromString(sortMode.toString());
    }
    if (valueMode == null) {
        valueMode = order == SortOrder.DESC ? MultiValueMode.MAX : MultiValueMode.MIN;
    }
    final Nested nested;
    if (nestedSort != null) {
        // new nested sorts takes priority
        validateMaxChildrenExistOnlyInTopLevelNestedSort(context, nestedSort);
        nested = resolveNested(context, nestedSort);
    } else {
        nested = resolveNested(context, nestedPath, nestedFilter);
    }
    switch(type) {
        case STRING:
            final StringSortScript.Factory factory = context.compile(script, StringSortScript.CONTEXT);
            final StringSortScript.LeafFactory searchScript = factory.newFactory(script.getParams(), context.lookup());
            return new BytesRefFieldComparatorSource(null, null, valueMode, nested) {

                StringSortScript leafScript;

                @Override
                protected SortedBinaryDocValues getValues(LeafReaderContext context) throws IOException {
                    leafScript = searchScript.newInstance(context);
                    final BinaryDocValues values = new AbstractBinaryDocValues() {

                        final BytesRefBuilder spare = new BytesRefBuilder();

                        @Override
                        public boolean advanceExact(int doc) throws IOException {
                            leafScript.setDocument(doc);
                            return true;
                        }

                        @Override
                        public BytesRef binaryValue() {
                            spare.copyChars(leafScript.execute());
                            return spare.get();
                        }
                    };
                    return FieldData.singleton(values);
                }

                @Override
                protected void setScorer(Scorable scorer) {
                    leafScript.setScorer(scorer);
                }

                @Override
                public BucketedSort newBucketedSort(BigArrays bigArrays, SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
                    throw new IllegalArgumentException("error building sort for [_script]: " + "script sorting only supported on [numeric] scripts but was [" + type + "]");
                }
            };
        case NUMBER:
            final NumberSortScript.Factory numberSortFactory = context.compile(script, NumberSortScript.CONTEXT);
            final NumberSortScript.LeafFactory numberSortScript = numberSortFactory.newFactory(script.getParams(), context.lookup());
            return new DoubleValuesComparatorSource(null, Double.MAX_VALUE, valueMode, nested) {

                NumberSortScript leafScript;

                @Override
                protected SortedNumericDoubleValues getValues(LeafReaderContext context) throws IOException {
                    leafScript = numberSortScript.newInstance(context);
                    final NumericDoubleValues values = new NumericDoubleValues() {

                        @Override
                        public boolean advanceExact(int doc) throws IOException {
                            leafScript.setDocument(doc);
                            return true;
                        }

                        @Override
                        public double doubleValue() {
                            return leafScript.execute();
                        }
                    };
                    return FieldData.singleton(values);
                }

                @Override
                protected void setScorer(Scorable scorer) {
                    leafScript.setScorer(scorer);
                }
            };
        default:
            throw new QueryShardException(context, "custom script sort type [" + type + "] not supported");
    }
}
Also used : BytesRefBuilder(org.apache.lucene.util.BytesRefBuilder) DoubleValuesComparatorSource(org.opensearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource) Scorable(org.apache.lucene.search.Scorable) DocValueFormat(org.opensearch.search.DocValueFormat) Nested(org.opensearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested) BytesRefFieldComparatorSource(org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource) StringSortScript(org.opensearch.script.StringSortScript) SortedNumericDoubleValues(org.opensearch.index.fielddata.SortedNumericDoubleValues) NumericDoubleValues(org.opensearch.index.fielddata.NumericDoubleValues) AbstractBinaryDocValues(org.opensearch.index.fielddata.AbstractBinaryDocValues) MultiValueMode(org.opensearch.search.MultiValueMode) AbstractBinaryDocValues(org.opensearch.index.fielddata.AbstractBinaryDocValues) SortedBinaryDocValues(org.opensearch.index.fielddata.SortedBinaryDocValues) BinaryDocValues(org.apache.lucene.index.BinaryDocValues) NumberSortScript(org.opensearch.script.NumberSortScript) BigArrays(org.opensearch.common.util.BigArrays) LeafReaderContext(org.apache.lucene.index.LeafReaderContext) QueryShardException(org.opensearch.index.query.QueryShardException)

Example 4 with BytesRefFieldComparatorSource

use of org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource in project OpenSearch by opensearch-project.

the class LuceneTests method randomSortFieldCustomComparatorSource.

private static Tuple<SortField, SortField> randomSortFieldCustomComparatorSource() {
    String field = randomAlphaOfLengthBetween(3, 10);
    IndexFieldData.XFieldComparatorSource comparatorSource;
    boolean reverse = randomBoolean();
    Object missingValue = null;
    switch(randomIntBetween(0, 3)) {
        case 0:
            comparatorSource = new LongValuesComparatorSource(null, randomBoolean() ? randomLong() : null, randomFrom(MultiValueMode.values()), null);
            break;
        case 1:
            comparatorSource = new DoubleValuesComparatorSource(null, randomBoolean() ? randomDouble() : null, randomFrom(MultiValueMode.values()), null);
            break;
        case 2:
            comparatorSource = new FloatValuesComparatorSource(null, randomBoolean() ? randomFloat() : null, randomFrom(MultiValueMode.values()), null);
            break;
        case 3:
            comparatorSource = new BytesRefFieldComparatorSource(null, randomBoolean() ? "_first" : "_last", randomFrom(MultiValueMode.values()), null);
            missingValue = comparatorSource.missingValue(reverse);
            break;
        default:
            throw new UnsupportedOperationException();
    }
    SortField sortField = new SortField(field, comparatorSource, reverse);
    SortField expected = new SortField(field, comparatorSource.reducedType(), reverse);
    expected.setMissingValue(missingValue);
    return Tuple.tuple(sortField, expected);
}
Also used : DoubleValuesComparatorSource(org.opensearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource) FloatValuesComparatorSource(org.opensearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource) LongValuesComparatorSource(org.opensearch.index.fielddata.fieldcomparator.LongValuesComparatorSource) BytesRefFieldComparatorSource(org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource) IndexFieldData(org.opensearch.index.fielddata.IndexFieldData) SortField(org.apache.lucene.search.SortField) SortedSetSortField(org.apache.lucene.search.SortedSetSortField) SortedNumericSortField(org.apache.lucene.search.SortedNumericSortField)

Example 5 with BytesRefFieldComparatorSource

use of org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource in project OpenSearch by opensearch-project.

the class AbstractStringFieldDataTestCase method testNestedSorting.

public void testNestedSorting(MultiValueMode sortMode) throws IOException {
    final String[] values = new String[randomIntBetween(2, 20)];
    for (int i = 0; i < values.length; ++i) {
        values[i] = TestUtil.randomSimpleString(random());
    }
    final int numParents = scaledRandomIntBetween(10, 3072);
    List<Document> docs = new ArrayList<>();
    FixedBitSet parents = new FixedBitSet(64);
    for (int i = 0; i < numParents; ++i) {
        docs.clear();
        final int numChildren = randomInt(4);
        for (int j = 0; j < numChildren; ++j) {
            final Document child = new Document();
            final int numValues = randomInt(3);
            for (int k = 0; k < numValues; ++k) {
                final String value = RandomPicks.randomFrom(random(), values);
                addField(child, "text", value);
            }
            docs.add(child);
        }
        final Document parent = new Document();
        parent.add(new StringField("type", "parent", Store.YES));
        final String value = RandomPicks.randomFrom(random(), values);
        if (value != null) {
            addField(parent, "text", value);
        }
        docs.add(parent);
        int bit = parents.prevSetBit(parents.length() - 1) + docs.size();
        parents = FixedBitSet.ensureCapacity(parents, bit);
        parents.set(bit);
        writer.addDocuments(docs);
        if (randomInt(10) == 0) {
            writer.commit();
        }
    }
    DirectoryReader directoryReader = DirectoryReader.open(writer);
    directoryReader = OpenSearchDirectoryReader.wrap(directoryReader, new ShardId(indexService.index(), 0));
    IndexSearcher searcher = new IndexSearcher(directoryReader);
    IndexFieldData<?> fieldData = getForField("text");
    final Object missingValue;
    switch(randomInt(4)) {
        case 0:
            missingValue = "_first";
            break;
        case 1:
            missingValue = "_last";
            break;
        case 2:
            missingValue = new BytesRef(RandomPicks.randomFrom(random(), values));
            break;
        default:
            missingValue = new BytesRef(TestUtil.randomSimpleString(random()));
            break;
    }
    Query parentFilter = new TermQuery(new Term("type", "parent"));
    Query childFilter = Queries.not(parentFilter);
    Nested nested = createNested(searcher, parentFilter, childFilter);
    BytesRefFieldComparatorSource nestedComparatorSource = new BytesRefFieldComparatorSource(fieldData, missingValue, sortMode, nested);
    ToParentBlockJoinQuery query = new ToParentBlockJoinQuery(new ConstantScoreQuery(childFilter), new QueryBitSetProducer(parentFilter), ScoreMode.None);
    Sort sort = new Sort(new SortField("text", nestedComparatorSource));
    TopFieldDocs topDocs = searcher.search(query, randomIntBetween(1, numParents), sort);
    assertTrue(topDocs.scoreDocs.length > 0);
    BytesRef previous = null;
    for (int i = 0; i < topDocs.scoreDocs.length; ++i) {
        final int docID = topDocs.scoreDocs[i].doc;
        assertTrue("expected " + docID + " to be a parent", parents.get(docID));
        BytesRef cmpValue = null;
        for (int child = parents.prevSetBit(docID - 1) + 1; child < docID; ++child) {
            String[] sVals = searcher.doc(child).getValues("text");
            final BytesRef[] vals;
            if (sVals.length == 0) {
                vals = new BytesRef[0];
            } else {
                vals = new BytesRef[sVals.length];
                for (int j = 0; j < vals.length; ++j) {
                    vals[j] = new BytesRef(sVals[j]);
                }
            }
            for (BytesRef value : vals) {
                if (cmpValue == null) {
                    cmpValue = value;
                } else if (sortMode == MultiValueMode.MIN && value.compareTo(cmpValue) < 0) {
                    cmpValue = value;
                } else if (sortMode == MultiValueMode.MAX && value.compareTo(cmpValue) > 0) {
                    cmpValue = value;
                }
            }
        }
        if (cmpValue == null) {
            if ("_first".equals(missingValue)) {
                cmpValue = new BytesRef();
            } else if ("_last".equals(missingValue) == false) {
                cmpValue = (BytesRef) missingValue;
            }
        }
        if (previous != null && cmpValue != null) {
            assertTrue(previous.utf8ToString() + "   /   " + cmpValue.utf8ToString(), previous.compareTo(cmpValue) <= 0);
        }
        previous = cmpValue;
    }
    searcher.getIndexReader().close();
}
Also used : IndexSearcher(org.apache.lucene.search.IndexSearcher) Query(org.apache.lucene.search.Query) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) MatchAllDocsQuery(org.apache.lucene.search.MatchAllDocsQuery) TermQuery(org.apache.lucene.search.TermQuery) ToParentBlockJoinQuery(org.apache.lucene.search.join.ToParentBlockJoinQuery) ArrayList(java.util.ArrayList) Nested(org.opensearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested) TopFieldDocs(org.apache.lucene.search.TopFieldDocs) SortField(org.apache.lucene.search.SortField) Document(org.apache.lucene.document.Document) ShardId(org.opensearch.index.shard.ShardId) FixedBitSet(org.apache.lucene.util.FixedBitSet) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) QueryBitSetProducer(org.apache.lucene.search.join.QueryBitSetProducer) Sort(org.apache.lucene.search.Sort) BytesRef(org.apache.lucene.util.BytesRef) TermQuery(org.apache.lucene.search.TermQuery) OpenSearchDirectoryReader(org.opensearch.common.lucene.index.OpenSearchDirectoryReader) DirectoryReader(org.apache.lucene.index.DirectoryReader) BytesRefFieldComparatorSource(org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource) Term(org.apache.lucene.index.Term) ToParentBlockJoinQuery(org.apache.lucene.search.join.ToParentBlockJoinQuery) StringField(org.apache.lucene.document.StringField)

Aggregations

BytesRefFieldComparatorSource (org.opensearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource)5 SortField (org.apache.lucene.search.SortField)4 ArrayList (java.util.ArrayList)2 Document (org.apache.lucene.document.Document)2 StringField (org.apache.lucene.document.StringField)2 DirectoryReader (org.apache.lucene.index.DirectoryReader)2 Term (org.apache.lucene.index.Term)2 ConstantScoreQuery (org.apache.lucene.search.ConstantScoreQuery)2 IndexSearcher (org.apache.lucene.search.IndexSearcher)2 Query (org.apache.lucene.search.Query)2 Sort (org.apache.lucene.search.Sort)2 SortedSetSortField (org.apache.lucene.search.SortedSetSortField)2 TermQuery (org.apache.lucene.search.TermQuery)2 TopFieldDocs (org.apache.lucene.search.TopFieldDocs)2 QueryBitSetProducer (org.apache.lucene.search.join.QueryBitSetProducer)2 ToParentBlockJoinQuery (org.apache.lucene.search.join.ToParentBlockJoinQuery)2 OpenSearchDirectoryReader (org.opensearch.common.lucene.index.OpenSearchDirectoryReader)2 Nested (org.opensearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested)2 DoubleValuesComparatorSource (org.opensearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource)2 ShardId (org.opensearch.index.shard.ShardId)2