Search in sources :

Example 26 with XContentType

use of org.opensearch.common.xcontent.XContentType 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 27 with XContentType

use of org.opensearch.common.xcontent.XContentType in project OpenSearch by opensearch-project.

the class AliasActionsTests method testFromToXContent.

public void testFromToXContent() throws IOException {
    for (int runs = 0; runs < 20; runs++) {
        AliasActions action = randomAliasAction();
        XContentType xContentType = randomFrom(XContentType.values());
        BytesReference shuffled = toShuffledXContent(action, xContentType, ToXContent.EMPTY_PARAMS, false, "filter");
        AliasActions parsedAction;
        try (XContentParser parser = createParser(xContentType.xContent(), shuffled)) {
            parsedAction = AliasActions.fromXContent(parser);
            assertNull(parser.nextToken());
        }
        assertThat(parsedAction, equalTo(action));
    }
}
Also used : BytesReference(org.opensearch.common.bytes.BytesReference) XContentType(org.opensearch.common.xcontent.XContentType) AliasActions(org.opensearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions) XContentParser(org.opensearch.common.xcontent.XContentParser)

Example 28 with XContentType

use of org.opensearch.common.xcontent.XContentType in project OpenSearch by opensearch-project.

the class CloseIndexResponseTests method testToXContent.

/**
 * Test that random responses can be written to xcontent without errors.
 * Also check some specific simple cases for output.
 */
public void testToXContent() throws IOException {
    CloseIndexResponse response = randomResponse();
    XContentType xContentType = randomFrom(XContentType.values());
    try (XContentBuilder builder = XContentBuilder.builder(xContentType.xContent())) {
        response.toXContent(builder, ToXContent.EMPTY_PARAMS);
    }
    Index index = new Index("test", "uuid");
    IndexResult indexResult = new CloseIndexResponse.IndexResult(index);
    CloseIndexResponse closeIndexResponse = new CloseIndexResponse(true, true, Collections.singletonList(indexResult));
    assertEquals("{\"acknowledged\":true,\"shards_acknowledged\":true,\"indices\":{\"test\":{\"closed\":true}}}", Strings.toString(closeIndexResponse));
    CloseIndexResponse.ShardResult[] shards = new CloseIndexResponse.ShardResult[1];
    shards[0] = new CloseIndexResponse.ShardResult(0, new CloseIndexResponse.ShardResult.Failure[] { new CloseIndexResponse.ShardResult.Failure("test", 0, new ActionNotFoundTransportException("test"), "nodeId") });
    indexResult = new CloseIndexResponse.IndexResult(index, shards);
    closeIndexResponse = new CloseIndexResponse(true, true, Collections.singletonList(indexResult));
    assertEquals("{\"acknowledged\":true,\"shards_acknowledged\":true," + "\"indices\":{\"test\":{\"closed\":false,\"failedShards\":{\"0\":{" + "\"failures\":[{\"node\":\"nodeId\",\"shard\":0,\"index\":\"test\",\"status\":\"INTERNAL_SERVER_ERROR\"," + "\"reason\":{\"type\":\"action_not_found_transport_exception\"," + "\"reason\":\"No handler for action [test]\"}}]}}}}}", Strings.toString(closeIndexResponse));
}
Also used : XContentType(org.opensearch.common.xcontent.XContentType) IndexResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.IndexResult) IndexResult(org.opensearch.action.admin.indices.close.CloseIndexResponse.IndexResult) Index(org.opensearch.index.Index) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder) ActionNotFoundTransportException(org.opensearch.transport.ActionNotFoundTransportException)

Example 29 with XContentType

use of org.opensearch.common.xcontent.XContentType in project OpenSearch by opensearch-project.

the class RolloverRequestTests method testUnknownFields.

public void testUnknownFields() throws IOException {
    final RolloverRequest request = new RolloverRequest();
    XContentType xContentType = randomFrom(XContentType.values());
    final XContentBuilder builder = XContentFactory.contentBuilder(xContentType);
    builder.startObject();
    {
        builder.startObject("conditions");
        builder.field("max_age", "10d");
        builder.endObject();
    }
    builder.endObject();
    BytesReference mutated = XContentTestUtils.insertRandomFields(xContentType, BytesReference.bytes(builder), null, random());
    expectThrows(XContentParseException.class, () -> request.fromXContent(createParser(xContentType.xContent(), mutated)));
}
Also used : BytesReference(org.opensearch.common.bytes.BytesReference) XContentType(org.opensearch.common.xcontent.XContentType) XContentBuilder(org.opensearch.common.xcontent.XContentBuilder)

Example 30 with XContentType

use of org.opensearch.common.xcontent.XContentType in project OpenSearch by opensearch-project.

the class PutMappingRequestTests method testToAndFromXContent.

public void testToAndFromXContent() throws IOException {
    final PutMappingRequest putMappingRequest = createTestItem();
    boolean humanReadable = randomBoolean();
    final XContentType xContentType = randomFrom(XContentType.values());
    BytesReference originalBytes = toShuffledXContent(putMappingRequest, xContentType, EMPTY_PARAMS, humanReadable);
    PutMappingRequest parsedPutMappingRequest = new PutMappingRequest();
    parsedPutMappingRequest.source(originalBytes, xContentType);
    assertMappingsEqual(putMappingRequest.source(), parsedPutMappingRequest.source());
}
Also used : BytesReference(org.opensearch.common.bytes.BytesReference) XContentType(org.opensearch.common.xcontent.XContentType)

Aggregations

XContentType (org.opensearch.common.xcontent.XContentType)148 BytesReference (org.opensearch.common.bytes.BytesReference)99 XContentParser (org.opensearch.common.xcontent.XContentParser)85 XContentBuilder (org.opensearch.common.xcontent.XContentBuilder)44 IOException (java.io.IOException)31 HashMap (java.util.HashMap)31 Map (java.util.Map)30 ToXContent (org.opensearch.common.xcontent.ToXContent)22 List (java.util.List)18 IndexRequest (org.opensearch.action.index.IndexRequest)16 ArrayList (java.util.ArrayList)15 Predicate (java.util.function.Predicate)14 OpenSearchTestCase (org.opensearch.test.OpenSearchTestCase)14 XContentTestUtils.insertRandomFields (org.opensearch.test.XContentTestUtils.insertRandomFields)12 Matchers.containsString (org.hamcrest.Matchers.containsString)11 DocWriteRequest (org.opensearch.action.DocWriteRequest)11 XContentHelper.toXContent (org.opensearch.common.xcontent.XContentHelper.toXContent)11 Collections (java.util.Collections)10 DeleteRequest (org.opensearch.action.delete.DeleteRequest)10 OpenSearchAssertions.assertToXContentEquivalent (org.opensearch.test.hamcrest.OpenSearchAssertions.assertToXContentEquivalent)10