Search in sources :

Example 16 with DocumentMapper

use of org.opensearch.index.mapper.DocumentMapper in project OpenSearch by opensearch-project.

the class FetchPhase method prepareNonNestedHitContext.

/**
 * Resets the provided {@link HitContext} with information on the current
 * document. This includes the following:
 *   - Adding an initial {@link SearchHit} instance.
 *   - Loading the document source and setting it on {@link SourceLookup}. This allows
 *     fetch subphases that use the hit context to access the preloaded source.
 */
private HitContext prepareNonNestedHitContext(SearchContext context, SearchLookup lookup, FieldsVisitor fieldsVisitor, int docId, Map<String, Set<String>> storedToRequestedFields, LeafReaderContext subReaderContext, CheckedBiConsumer<Integer, FieldsVisitor, IOException> fieldReader) throws IOException {
    int subDocId = docId - subReaderContext.docBase;
    DocumentMapper documentMapper = context.mapperService().documentMapper();
    Text typeText = documentMapper.typeText();
    if (fieldsVisitor == null) {
        SearchHit hit = new SearchHit(docId, null, null, null);
        return new HitContext(hit, subReaderContext, subDocId, lookup.source());
    } else {
        SearchHit hit;
        loadStoredFields(context.mapperService(), fieldReader, fieldsVisitor, subDocId);
        Uid uid = fieldsVisitor.uid();
        if (fieldsVisitor.fields().isEmpty() == false) {
            Map<String, DocumentField> docFields = new HashMap<>();
            Map<String, DocumentField> metaFields = new HashMap<>();
            fillDocAndMetaFields(context, fieldsVisitor, storedToRequestedFields, docFields, metaFields);
            hit = new SearchHit(docId, uid.id(), docFields, metaFields);
        } else {
            hit = new SearchHit(docId, uid.id(), emptyMap(), emptyMap());
        }
        HitContext hitContext = new HitContext(hit, subReaderContext, subDocId, lookup.source());
        if (fieldsVisitor.source() != null) {
            hitContext.sourceLookup().setSource(fieldsVisitor.source());
        }
        return hitContext;
    }
}
Also used : Uid(org.opensearch.index.mapper.Uid) SearchHit(org.opensearch.search.SearchHit) DocumentField(org.opensearch.common.document.DocumentField) HashMap(java.util.HashMap) DocumentMapper(org.opensearch.index.mapper.DocumentMapper) Text(org.opensearch.common.text.Text) HitContext(org.opensearch.search.fetch.FetchSubPhase.HitContext)

Example 17 with DocumentMapper

use of org.opensearch.index.mapper.DocumentMapper in project OpenSearch by opensearch-project.

the class FetchPhase method prepareNestedHitContext.

/**
 * Resets the provided {@link HitContext} with information on the current
 * nested document. This includes the following:
 *   - Adding an initial {@link SearchHit} instance.
 *   - Loading the document source, filtering it based on the nested document ID, then
 *     setting it on {@link SourceLookup}. This allows fetch subphases that use the hit
 *     context to access the preloaded source.
 */
@SuppressWarnings("unchecked")
private HitContext prepareNestedHitContext(SearchContext context, int nestedTopDocId, int rootDocId, Map<String, Set<String>> storedToRequestedFields, LeafReaderContext subReaderContext, CheckedBiConsumer<Integer, FieldsVisitor, IOException> storedFieldReader) 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.
    boolean needSource = sourceRequired(context) || context.highlight() != null;
    Uid rootId;
    Map<String, Object> rootSourceAsMap = null;
    XContentType rootSourceContentType = null;
    int nestedDocId = nestedTopDocId - subReaderContext.docBase;
    if (context instanceof InnerHitsContext.InnerHitSubContext) {
        InnerHitsContext.InnerHitSubContext innerHitsContext = (InnerHitsContext.InnerHitSubContext) context;
        rootId = innerHitsContext.getRootId();
        if (needSource) {
            SourceLookup rootLookup = innerHitsContext.getRootLookup();
            rootSourceAsMap = rootLookup.loadSourceIfNeeded();
            rootSourceContentType = rootLookup.sourceContentType();
        }
    } else {
        FieldsVisitor rootFieldsVisitor = new FieldsVisitor(needSource);
        loadStoredFields(context.mapperService(), storedFieldReader, rootFieldsVisitor, rootDocId);
        rootFieldsVisitor.postProcess(context.mapperService());
        rootId = rootFieldsVisitor.uid();
        if (needSource) {
            if (rootFieldsVisitor.source() != null) {
                Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(rootFieldsVisitor.source(), false);
                rootSourceAsMap = tuple.v2();
                rootSourceContentType = tuple.v1();
            } else {
                rootSourceAsMap = Collections.emptyMap();
            }
        }
    }
    Map<String, DocumentField> docFields = emptyMap();
    Map<String, DocumentField> metaFields = emptyMap();
    if (context.hasStoredFields() && !context.storedFieldsContext().fieldNames().isEmpty()) {
        FieldsVisitor nestedFieldsVisitor = new CustomFieldsVisitor(storedToRequestedFields.keySet(), false);
        loadStoredFields(context.mapperService(), storedFieldReader, nestedFieldsVisitor, nestedDocId);
        if (nestedFieldsVisitor.fields().isEmpty() == false) {
            docFields = new HashMap<>();
            metaFields = new HashMap<>();
            fillDocAndMetaFields(context, nestedFieldsVisitor, storedToRequestedFields, docFields, metaFields);
        }
    }
    DocumentMapper documentMapper = context.mapperService().documentMapper();
    ObjectMapper nestedObjectMapper = documentMapper.findNestedObjectMapper(nestedDocId, context, subReaderContext);
    assert nestedObjectMapper != null;
    SearchHit.NestedIdentity nestedIdentity = getInternalNestedIdentity(context, nestedDocId, subReaderContext, context.mapperService(), nestedObjectMapper);
    SearchHit hit = new SearchHit(nestedTopDocId, rootId.id(), nestedIdentity, docFields, metaFields);
    // Use a clean, fresh SourceLookup
    HitContext hitContext = new HitContext(hit, subReaderContext, nestedDocId, new SourceLookup());
    if (rootSourceAsMap != null && rootSourceAsMap.isEmpty() == false) {
        // 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, rootSourceAsMap);
            List<?> nestedParsedSource;
            if (extractedValue instanceof List) {
                // nested field has an array value in the _source
                nestedParsedSource = (List<?>) 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(extractedValue);
            } else {
                throw new IllegalStateException("extracted source isn't an object or an array");
            }
            if ((nestedParsedSource.get(0) instanceof Map) == false && nestedObjectMapper.parentObjectMapperAreNested(context.mapperService()) == false) {
                // This is why only the first element of nestedParsedSource needs to be checked.
                throw new IllegalArgumentException("Cannot execute inner hits. One or more parent object fields of nested field [" + nestedObjectMapper.name() + "] are not nested. All parent fields need to be nested fields too");
            }
            rootSourceAsMap = (Map<String, Object>) nestedParsedSource.get(nested.getOffset());
            if (nested.getChild() == null) {
                current.put(nestedPath, rootSourceAsMap);
            } else {
                Map<String, Object> next = new HashMap<>();
                current.put(nestedPath, next);
                current = next;
            }
        }
        hitContext.sourceLookup().setSource(nestedSourceAsMap);
        hitContext.sourceLookup().setSourceContentType(rootSourceContentType);
    }
    return hitContext;
}
Also used : FieldsVisitor(org.opensearch.index.fieldvisitor.FieldsVisitor) CustomFieldsVisitor(org.opensearch.index.fieldvisitor.CustomFieldsVisitor) DocumentField(org.opensearch.common.document.DocumentField) SearchHit(org.opensearch.search.SearchHit) HashMap(java.util.HashMap) HitContext(org.opensearch.search.fetch.FetchSubPhase.HitContext) XContentType(org.opensearch.common.xcontent.XContentType) List(java.util.List) ArrayList(java.util.ArrayList) ObjectMapper(org.opensearch.index.mapper.ObjectMapper) SourceLookup(org.opensearch.search.lookup.SourceLookup) DocumentMapper(org.opensearch.index.mapper.DocumentMapper) Uid(org.opensearch.index.mapper.Uid) CustomFieldsVisitor(org.opensearch.index.fieldvisitor.CustomFieldsVisitor) InnerHitsContext(org.opensearch.search.fetch.subphase.InnerHitsContext) Map(java.util.Map) HashMap(java.util.HashMap) Collections.emptyMap(java.util.Collections.emptyMap)

Example 18 with DocumentMapper

use of org.opensearch.index.mapper.DocumentMapper in project OpenSearch by opensearch-project.

the class IndexShard method get.

public Engine.GetResult get(Engine.Get get) {
    readAllowed();
    DocumentMapper mapper = mapperService.documentMapper();
    if (mapper == null) {
        return GetResult.NOT_EXISTS;
    }
    return getEngine().get(get, this::acquireSearcher);
}
Also used : DocumentMapper(org.opensearch.index.mapper.DocumentMapper)

Example 19 with DocumentMapper

use of org.opensearch.index.mapper.DocumentMapper in project OpenSearch by opensearch-project.

the class LeafFieldsLookup method loadFieldData.

private FieldLookup loadFieldData(String name) {
    FieldLookup data = cachedFieldData.get(name);
    if (data == null) {
        MappedFieldType fieldType = mapperService.fieldType(name);
        if (fieldType == null) {
            throw new IllegalArgumentException("No field found for [" + name + "] in mapping");
        }
        data = new FieldLookup(fieldType);
        cachedFieldData.put(name, data);
    }
    if (data.fields() == null) {
        List<Object> values;
        if (TypeFieldMapper.NAME.equals(data.fieldType().name())) {
            TypeFieldMapper.emitTypesDeprecationWarning();
            values = new ArrayList<>(1);
            final DocumentMapper mapper = mapperService.documentMapper();
            if (mapper != null) {
                values.add(mapper.type());
            }
        } else {
            values = new ArrayList<Object>(2);
            SingleFieldsVisitor visitor = new SingleFieldsVisitor(data.fieldType(), values);
            try {
                reader.document(docId, visitor);
            } catch (IOException e) {
                throw new OpenSearchParseException("failed to load field [{}]", e, name);
            }
        }
        data.fields(singletonMap(data.fieldType().name(), values));
    }
    return data;
}
Also used : OpenSearchParseException(org.opensearch.OpenSearchParseException) DocumentMapper(org.opensearch.index.mapper.DocumentMapper) MappedFieldType(org.opensearch.index.mapper.MappedFieldType) SingleFieldsVisitor(org.opensearch.index.fieldvisitor.SingleFieldsVisitor) IOException(java.io.IOException)

Example 20 with DocumentMapper

use of org.opensearch.index.mapper.DocumentMapper in project OpenSearch by opensearch-project.

the class CompositeAggregatorTests method mapperServiceMock.

@Override
protected MapperService mapperServiceMock() {
    MapperService mapperService = mock(MapperService.class);
    DocumentMapper mapper = mock(DocumentMapper.class);
    when(mapper.typeText()).thenReturn(new Text("_doc"));
    when(mapper.type()).thenReturn("_doc");
    when(mapperService.documentMapper()).thenReturn(mapper);
    return mapperService;
}
Also used : DocumentMapper(org.opensearch.index.mapper.DocumentMapper) Text(org.opensearch.common.text.Text) MapperService(org.opensearch.index.mapper.MapperService)

Aggregations

DocumentMapper (org.opensearch.index.mapper.DocumentMapper)55 ParsedDocument (org.opensearch.index.mapper.ParsedDocument)23 Matchers.containsString (org.hamcrest.Matchers.containsString)22 CompressedXContent (org.opensearch.common.compress.CompressedXContent)19 SourceToParse (org.opensearch.index.mapper.SourceToParse)19 IndexableField (org.apache.lucene.index.IndexableField)17 MapperService (org.opensearch.index.mapper.MapperService)17 XContentBuilder (org.opensearch.common.xcontent.XContentBuilder)14 HashMap (java.util.HashMap)13 IOException (java.io.IOException)12 TextFieldMapper (org.opensearch.index.mapper.TextFieldMapper)12 Map (java.util.Map)11 IndexService (org.opensearch.index.IndexService)11 IndexSettings (org.opensearch.index.IndexSettings)11 Mapper (org.opensearch.index.mapper.Mapper)11 Collections (java.util.Collections)8 BytesRef (org.apache.lucene.util.BytesRef)8 Arrays (java.util.Arrays)7 Collection (java.util.Collection)7 DocValuesType (org.apache.lucene.index.DocValuesType)7