Search in sources :

Example 1 with ObjectMapper

use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.

the class SortBuilder method resolveNested.

protected static Nested resolveNested(QueryShardContext context, String nestedPath, QueryBuilder nestedFilter) throws IOException {
    Nested nested = null;
    if (nestedPath != null) {
        BitSetProducer rootDocumentsFilter = context.bitsetFilter(Queries.newNonNestedFilter());
        ObjectMapper nestedObjectMapper = context.getObjectMapper(nestedPath);
        if (nestedObjectMapper == null) {
            throw new QueryShardException(context, "[nested] failed to find nested object under path [" + nestedPath + "]");
        }
        if (!nestedObjectMapper.nested().isNested()) {
            throw new QueryShardException(context, "[nested] nested object under path [" + nestedPath + "] is not of nested type");
        }
        Query innerDocumentsQuery;
        if (nestedFilter != null) {
            context.nestedScope().nextLevel(nestedObjectMapper);
            innerDocumentsQuery = QueryBuilder.rewriteQuery(nestedFilter, context).toFilter(context);
            context.nestedScope().previousLevel();
        } else {
            innerDocumentsQuery = nestedObjectMapper.nestedTypeFilter();
        }
        nested = new Nested(rootDocumentsFilter, innerDocumentsQuery);
    }
    return nested;
}
Also used : Query(org.apache.lucene.search.Query) BitSetProducer(org.apache.lucene.search.join.BitSetProducer) Nested(org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested) QueryShardException(org.elasticsearch.index.query.QueryShardException) ObjectMapper(org.elasticsearch.index.mapper.ObjectMapper)

Example 2 with ObjectMapper

use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.

the class FetchPhase method createNestedSearchHit.

private SearchHit createNestedSearchHit(SearchContext context, int nestedTopDocId, int nestedSubDocId, int rootSubDocId, Set<String> fieldNames, List<String> fieldNamePatterns, LeafReaderContext subReaderContext) throws IOException {
    // Also if highlighting is requested on nested documents we need to fetch the _source from the root document,
    // otherwise highlighting will attempt to fetch the _source from the nested doc, which will fail,
    // because the entire _source is only stored with the root document.
    final FieldsVisitor rootFieldsVisitor = new FieldsVisitor(context.sourceRequested() || context.highlight() != null);
    loadStoredFields(context, subReaderContext, rootFieldsVisitor, rootSubDocId);
    rootFieldsVisitor.postProcess(context.mapperService());
    Map<String, SearchHitField> searchFields = getSearchFields(context, nestedSubDocId, fieldNames, fieldNamePatterns, subReaderContext);
    DocumentMapper documentMapper = context.mapperService().documentMapper(rootFieldsVisitor.uid().type());
    SourceLookup sourceLookup = context.lookup().source();
    sourceLookup.setSegmentAndDocument(subReaderContext, nestedSubDocId);
    ObjectMapper nestedObjectMapper = documentMapper.findNestedObjectMapper(nestedSubDocId, context, subReaderContext);
    assert nestedObjectMapper != null;
    SearchHit.NestedIdentity nestedIdentity = getInternalNestedIdentity(context, nestedSubDocId, subReaderContext, documentMapper, nestedObjectMapper);
    BytesReference source = rootFieldsVisitor.source();
    if (source != null) {
        Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(source, true);
        Map<String, Object> sourceAsMap = tuple.v2();
        // Isolate the nested json array object that matches with nested hit and wrap it back into the same json
        // structure with the nested json array object being the actual content. The latter is important, so that
        // features like source filtering and highlighting work consistent regardless of whether the field points
        // to a json object array for consistency reasons on how we refer to fields
        Map<String, Object> nestedSourceAsMap = new HashMap<>();
        Map<String, Object> current = nestedSourceAsMap;
        for (SearchHit.NestedIdentity nested = nestedIdentity; nested != null; nested = nested.getChild()) {
            String nestedPath = nested.getField().string();
            current.put(nestedPath, new HashMap<>());
            Object extractedValue = XContentMapValues.extractValue(nestedPath, sourceAsMap);
            List<Map<String, Object>> nestedParsedSource;
            if (extractedValue instanceof List) {
                // nested field has an array value in the _source
                nestedParsedSource = (List<Map<String, Object>>) extractedValue;
            } else if (extractedValue instanceof Map) {
                // nested field has an object value in the _source. This just means the nested field has just one inner object, which is valid, but uncommon.
                nestedParsedSource = Collections.singletonList((Map<String, Object>) extractedValue);
            } else {
                throw new IllegalStateException("extracted source isn't an object or an array");
            }
            sourceAsMap = nestedParsedSource.get(nested.getOffset());
            if (nested.getChild() == null) {
                current.put(nestedPath, sourceAsMap);
            } else {
                Map<String, Object> next = new HashMap<>();
                current.put(nestedPath, next);
                current = next;
            }
        }
        context.lookup().source().setSource(nestedSourceAsMap);
        XContentType contentType = tuple.v1();
        BytesReference nestedSource = contentBuilder(contentType).map(sourceAsMap).bytes();
        context.lookup().source().setSource(nestedSource);
        context.lookup().source().setSourceContentType(contentType);
    }
    return new SearchHit(nestedTopDocId, rootFieldsVisitor.uid().id(), documentMapper.typeText(), nestedIdentity, searchFields);
}
Also used : BytesReference(org.elasticsearch.common.bytes.BytesReference) FieldsVisitor(org.elasticsearch.index.fieldvisitor.FieldsVisitor) CustomFieldsVisitor(org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor) SourceLookup(org.elasticsearch.search.lookup.SourceLookup) SearchHit(org.elasticsearch.search.SearchHit) HashMap(java.util.HashMap) DocumentMapper(org.elasticsearch.index.mapper.DocumentMapper) XContentType(org.elasticsearch.common.xcontent.XContentType) SearchHitField(org.elasticsearch.search.SearchHitField) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ObjectMapper(org.elasticsearch.index.mapper.ObjectMapper)

Example 3 with ObjectMapper

use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.

the class NestedQueryBuilder method doToQuery.

@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
    ObjectMapper nestedObjectMapper = context.getObjectMapper(path);
    if (nestedObjectMapper == null) {
        if (ignoreUnmapped) {
            return new MatchNoDocsQuery();
        } else {
            throw new IllegalStateException("[" + NAME + "] failed to find nested object under path [" + path + "]");
        }
    }
    if (!nestedObjectMapper.nested().isNested()) {
        throw new IllegalStateException("[" + NAME + "] nested object under path [" + path + "] is not of nested type");
    }
    final BitSetProducer parentFilter;
    Query innerQuery;
    ObjectMapper objectMapper = context.nestedScope().getObjectMapper();
    if (objectMapper == null) {
        parentFilter = context.bitsetFilter(Queries.newNonNestedFilter());
    } else {
        parentFilter = context.bitsetFilter(objectMapper.nestedTypeFilter());
    }
    try {
        context.nestedScope().nextLevel(nestedObjectMapper);
        innerQuery = this.query.toQuery(context);
    } finally {
        context.nestedScope().previousLevel();
    }
    // in its child space
    if (new NestedHelper(context.getMapperService()).mightMatchNonNestedDocs(innerQuery, path)) {
        innerQuery = Queries.filtered(innerQuery, nestedObjectMapper.nestedTypeFilter());
    }
    return new ESToParentBlockJoinQuery(innerQuery, parentFilter, scoreMode, objectMapper == null ? null : objectMapper.fullPath());
}
Also used : Query(org.apache.lucene.search.Query) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) ToParentBlockJoinQuery(org.apache.lucene.search.join.ToParentBlockJoinQuery) ESToParentBlockJoinQuery(org.elasticsearch.index.search.ESToParentBlockJoinQuery) BitSetProducer(org.apache.lucene.search.join.BitSetProducer) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) ESToParentBlockJoinQuery(org.elasticsearch.index.search.ESToParentBlockJoinQuery) NestedHelper(org.elasticsearch.index.search.NestedHelper) ObjectMapper(org.elasticsearch.index.mapper.ObjectMapper)

Example 4 with ObjectMapper

use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.

the class NestedScope method nextLevel.

/**
     * Sets the new current nested level and pushes old current nested level down the stack returns that level.
     */
public ObjectMapper nextLevel(ObjectMapper level) {
    ObjectMapper previous = levelStack.peek();
    levelStack.push(level);
    return previous;
}
Also used : ObjectMapper(org.elasticsearch.index.mapper.ObjectMapper)

Example 5 with ObjectMapper

use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.

the class InnerHitBuilder method build.

public InnerHitsContext.BaseInnerHits build(SearchContext parentSearchContext, InnerHitsContext innerHitsContext) throws IOException {
    QueryShardContext queryShardContext = parentSearchContext.getQueryShardContext();
    if (nestedPath != null) {
        ObjectMapper nestedObjectMapper = queryShardContext.getObjectMapper(nestedPath);
        if (nestedObjectMapper == null) {
            if (ignoreUnmapped == false) {
                throw new IllegalStateException("[" + query.getName() + "] no mapping found for type [" + nestedPath + "]");
            } else {
                return null;
            }
        }
        ObjectMapper parentObjectMapper = queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
        InnerHitsContext.NestedInnerHits nestedInnerHits = new InnerHitsContext.NestedInnerHits(name, parentSearchContext, parentObjectMapper, nestedObjectMapper);
        setupInnerHitsContext(queryShardContext, nestedInnerHits);
        if (childInnerHits != null) {
            buildChildInnerHits(parentSearchContext, nestedInnerHits);
        }
        queryShardContext.nestedScope().previousLevel();
        innerHitsContext.addInnerHitDefinition(nestedInnerHits);
        return nestedInnerHits;
    } else if (parentChildType != null) {
        DocumentMapper documentMapper = queryShardContext.documentMapper(parentChildType);
        if (documentMapper == null) {
            if (ignoreUnmapped == false) {
                throw new IllegalStateException("[" + query.getName() + "] no mapping found for type [" + parentChildType + "]");
            } else {
                return null;
            }
        }
        InnerHitsContext.ParentChildInnerHits parentChildInnerHits = new InnerHitsContext.ParentChildInnerHits(name, parentSearchContext, queryShardContext.getMapperService(), documentMapper);
        setupInnerHitsContext(queryShardContext, parentChildInnerHits);
        if (childInnerHits != null) {
            buildChildInnerHits(parentSearchContext, parentChildInnerHits);
        }
        innerHitsContext.addInnerHitDefinition(parentChildInnerHits);
        return parentChildInnerHits;
    } else {
        throw new IllegalStateException("Neither a nested or parent/child inner hit");
    }
}
Also used : DocumentMapper(org.elasticsearch.index.mapper.DocumentMapper) InnerHitsContext(org.elasticsearch.search.fetch.subphase.InnerHitsContext) ObjectMapper(org.elasticsearch.index.mapper.ObjectMapper)

Aggregations

ObjectMapper (org.elasticsearch.index.mapper.ObjectMapper)7 Query (org.apache.lucene.search.Query)3 BitSetProducer (org.apache.lucene.search.join.BitSetProducer)2 DocumentMapper (org.elasticsearch.index.mapper.DocumentMapper)2 SearchHit (org.elasticsearch.search.SearchHit)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 DocIdSetIterator (org.apache.lucene.search.DocIdSetIterator)1 MatchNoDocsQuery (org.apache.lucene.search.MatchNoDocsQuery)1 Scorer (org.apache.lucene.search.Scorer)1 Weight (org.apache.lucene.search.Weight)1 ToParentBlockJoinQuery (org.apache.lucene.search.join.ToParentBlockJoinQuery)1 BitSet (org.apache.lucene.util.BitSet)1 BytesReference (org.elasticsearch.common.bytes.BytesReference)1 XContentType (org.elasticsearch.common.xcontent.XContentType)1 Nested (org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested)1 CustomFieldsVisitor (org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor)1 FieldsVisitor (org.elasticsearch.index.fieldvisitor.FieldsVisitor)1