org.elasticsearch.index.search.child.AbstractChildTestCase.java Source code

Java tutorial

Introduction

Here is the source code for org.elasticsearch.index.search.child.AbstractChildTestCase.java

Source

/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.elasticsearch.index.search.child;

import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.BitSet;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.hamcrest.Description;
import org.hamcrest.StringDescription;

import java.io.IOException;

import static org.hamcrest.Matchers.equalTo;

public abstract class AbstractChildTestCase extends ESSingleNodeTestCase {

    /**
     * The name of the field within the child type that stores a score to use in test queries.
     * <p />
     * Its type is {@code double}.
     */
    protected static String CHILD_SCORE_NAME = "childScore";

    static SearchContext createSearchContext(String indexName, String parentType, String childType)
            throws IOException {
        Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_6_0).build();
        IndexService indexService = createIndex(indexName, settings);
        MapperService mapperService = indexService.mapperService();
        // Parent/child parsers require that the parent and child type to be presented in mapping
        // Sometimes we want a nested object field in the parent type that triggers nonNestedDocsFilter to be used
        mapperService.merge(parentType,
                new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(parentType, "nested_field",
                        random().nextBoolean() ? "type=nested" : "type=object").string()),
                MapperService.MergeReason.MAPPING_UPDATE, false);
        mapperService.merge(childType,
                new CompressedXContent(PutMappingRequest.buildFromSimplifiedDef(childType, "_parent",
                        "type=" + parentType, CHILD_SCORE_NAME, "type=double,doc_values=false").string()),
                MapperService.MergeReason.MAPPING_UPDATE, false);
        return createSearchContext(indexService);
    }

    static void assertBitSet(BitSet actual, BitSet expected, IndexSearcher searcher) throws IOException {
        assertBitSet(new BitDocIdSet(actual), new BitDocIdSet(expected), searcher);
    }

    static void assertBitSet(BitDocIdSet actual, BitDocIdSet expected, IndexSearcher searcher) throws IOException {
        if (!equals(expected, actual)) {
            Description description = new StringDescription();
            description.appendText(reason(actual, expected, searcher));
            description.appendText("\nExpected: ");
            description.appendValue(expected);
            description.appendText("\n     got: ");
            description.appendValue(actual);
            description.appendText("\n");
            throw new java.lang.AssertionError(description.toString());
        }
    }

    static boolean equals(BitDocIdSet expected, BitDocIdSet actual) {
        if (actual == null && expected == null) {
            return true;
        } else if (actual == null || expected == null) {
            return false;
        }
        BitSet actualBits = actual.bits();
        BitSet expectedBits = expected.bits();
        if (actualBits.length() != expectedBits.length()) {
            return false;
        }
        for (int i = 0; i < expectedBits.length(); i++) {
            if (expectedBits.get(i) != actualBits.get(i)) {
                return false;
            }
        }
        return true;
    }

    static String reason(BitDocIdSet actual, BitDocIdSet expected, IndexSearcher indexSearcher) throws IOException {
        StringBuilder builder = new StringBuilder();
        builder.append("expected cardinality:").append(expected.bits().cardinality()).append('\n');
        DocIdSetIterator iterator = expected.iterator();
        for (int doc = iterator.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = iterator.nextDoc()) {
            builder.append("Expected doc[").append(doc).append("] with id value ")
                    .append(indexSearcher.doc(doc).get(UidFieldMapper.NAME)).append('\n');
        }
        builder.append("actual cardinality: ").append(actual.bits().cardinality()).append('\n');
        iterator = actual.iterator();
        for (int doc = iterator.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = iterator.nextDoc()) {
            builder.append("Actual doc[").append(doc).append("] with id value ")
                    .append(indexSearcher.doc(doc).get(UidFieldMapper.NAME)).append('\n');
        }
        return builder.toString();
    }

    static void assertTopDocs(TopDocs actual, TopDocs expected) {
        assertThat("actual.totalHits != expected.totalHits", actual.totalHits, equalTo(expected.totalHits));
        assertThat("actual.getMaxScore() != expected.getMaxScore()", actual.getMaxScore(),
                equalTo(expected.getMaxScore()));
        assertThat("actual.scoreDocs.length != expected.scoreDocs.length", actual.scoreDocs.length,
                equalTo(actual.scoreDocs.length));
        for (int i = 0; i < actual.scoreDocs.length; i++) {
            ScoreDoc actualHit = actual.scoreDocs[i];
            ScoreDoc expectedHit = expected.scoreDocs[i];
            assertThat("actualHit.doc != expectedHit.doc", actualHit.doc, equalTo(expectedHit.doc));
            assertThat("actualHit.score != expectedHit.score", actualHit.score, equalTo(expectedHit.score));
        }
    }

    static BitSetProducer wrapWithBitSetFilter(Query filter) {
        return SearchContext.current().bitsetFilterCache().getBitSetProducer(filter);
    }

    static Query parseQuery(QueryBuilder queryBuilder) throws IOException {
        QueryParseContext context = new QueryParseContext(new Index("test"),
                SearchContext.current().queryParserService());
        XContentParser parser = XContentHelper.createParser(queryBuilder.buildAsBytes());
        context.reset(parser);
        return context.parseInnerQuery();
    }

}