Search in sources :

Example 11 with DocumentMapping

use of com.b2international.index.mapping.DocumentMapping in project snow-owl by b2ihealthcare.

the class EsIndexAdmin method create.

@Override
public void create() {
    log.info("Preparing '{}' indexes...", name);
    // register any type that requires a refresh at the end of the index create/open
    Set<DocumentMapping> mappingsToRefresh = Sets.newHashSet();
    // create number of indexes based on number of types
    for (DocumentMapping mapping : mappings.getMappings()) {
        final String index = getTypeIndex(mapping);
        final Map<String, Object> typeMapping = ImmutableMap.<String, Object>builder().put("date_detection", false).put("numeric_detection", false).put("dynamic_templates", List.of(stringsAsKeywords())).putAll(toProperties(mapping)).build();
        if (exists(mapping)) {
            // update mapping if required
            final MappingMetadata currentIndexMapping;
            try {
                final GetMappingsRequest getMappingsRequest = new GetMappingsRequest().indices(index);
                currentIndexMapping = client.indices().getMapping(getMappingsRequest).mappings().get(index);
            } catch (Exception e) {
                throw new IndexException(String.format("Failed to get mapping of '%s' for type '%s'", name, mapping.typeAsString()), e);
            }
            try {
                final ObjectNode newTypeMapping = mapper.valueToTree(typeMapping);
                final ObjectNode currentTypeMapping = mapper.valueToTree(currentIndexMapping.getSourceAsMap());
                SortedSet<String> compatibleChanges = Sets.newTreeSet();
                SortedSet<String> incompatibleChanges = Sets.newTreeSet();
                JsonDiff.diff(currentTypeMapping, newTypeMapping).forEach(change -> {
                    if (change.isAdd()) {
                        compatibleChanges.add(change.getFieldPath());
                    } else if (change.isMove() || change.isReplace()) {
                        incompatibleChanges.add(change.getFieldPath());
                    }
                });
                if (!incompatibleChanges.isEmpty()) {
                    log.warn("Cannot migrate index '{}' to new mapping with breaking changes on properties '{}'. Run repository reindex to migrate to new mapping schema or drop that index manually using the Elasticsearch API.", index, incompatibleChanges);
                } else if (!compatibleChanges.isEmpty()) {
                    log.info("Applying mapping changes {} in index {}", compatibleChanges, index);
                    PutMappingRequest putMappingRequest = new PutMappingRequest(index).source(typeMapping);
                    AcknowledgedResponse response = client.indices().updateMapping(putMappingRequest);
                    checkState(response.isAcknowledged(), "Failed to update mapping '%s' for type '%s'", name, mapping.typeAsString());
                    // new fields do not require reindex, they will be added to new documents, existing documents don't have any data that needs reindex
                    if (hasFieldAliasChange(compatibleChanges)) {
                        if (bulkIndexByScroll(client, mapping, Expressions.matchAll(), "update", null, /*no script, in place update of docs to pick up mapping changes*/
                        "mapping migration")) {
                            mappingsToRefresh.add(mapping);
                        }
                        log.info("Migrated documents to new mapping in index '{}'", index);
                    }
                }
            } catch (IOException e) {
                throw new IndexException(String.format("Failed to update mapping '%s' for type '%s'", name, mapping.typeAsString()), e);
            }
        } else {
            // create index
            final Map<String, Object> indexSettings;
            try {
                indexSettings = createIndexSettings();
                log.info("Configuring '{}' index with settings: {}", index, indexSettings);
            } catch (IOException e) {
                throw new IndexException("Couldn't prepare settings for index " + index, e);
            }
            final CreateIndexRequest createIndexRequest = new CreateIndexRequest(index).mapping(typeMapping).settings(indexSettings);
            try {
                final CreateIndexResponse response = client.indices().create(createIndexRequest);
                checkState(response.isAcknowledged(), "Failed to create index '%s' for type '%s'", name, mapping.typeAsString());
            } catch (Exception e) {
                throw new IndexException(String.format("Failed to create index '%s' for type '%s'", name, mapping.typeAsString()), e);
            }
        }
    }
    // wait until the cluster processes each index create request
    waitForYellowHealth(indices());
    if (!mappingsToRefresh.isEmpty()) {
        refresh(mappingsToRefresh);
    }
    log.info("'{}' indexes are ready.", name);
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) PutMappingRequest(org.elasticsearch.client.indices.PutMappingRequest) AcknowledgedResponse(org.elasticsearch.action.support.master.AcknowledgedResponse) IOException(java.io.IOException) GetMappingsRequest(org.elasticsearch.client.indices.GetMappingsRequest) DocumentMapping(com.b2international.index.mapping.DocumentMapping) IOException(java.io.IOException) CreateIndexRequest(org.elasticsearch.client.indices.CreateIndexRequest) CreateIndexResponse(org.elasticsearch.client.indices.CreateIndexResponse) MappingMetadata(org.elasticsearch.cluster.metadata.MappingMetadata)

Example 12 with DocumentMapping

use of com.b2international.index.mapping.DocumentMapping in project snow-owl by b2ihealthcare.

the class EsQueryBuilder method visit.

private void visit(NestedPredicate predicate) {
    final String nestedPath = toFieldPath(predicate);
    final DocumentMapping nestedMapping = mapping.getNestedMapping(predicate.getField());
    final EsQueryBuilder nestedQueryBuilder = new EsQueryBuilder(nestedMapping, settings, log, nestedPath);
    nestedQueryBuilder.visit(predicate.getExpression());
    needsScoring = nestedQueryBuilder.needsScoring;
    final QueryBuilder nestedQuery = nestedQueryBuilder.deque.pop();
    deque.push(QueryBuilders.nestedQuery(nestedPath, nestedQuery, ScoreMode.None));
}
Also used : DocumentMapping(com.b2international.index.mapping.DocumentMapping)

Aggregations

DocumentMapping (com.b2international.index.mapping.DocumentMapping)12 IOException (java.io.IOException)5 EsClient (com.b2international.index.es.client.EsClient)3 Maps.newHashMap (com.google.common.collect.Maps.newHashMap)3 CompareUtils (com.b2international.commons.CompareUtils)2 BadRequestException (com.b2international.commons.exceptions.BadRequestException)2 FormattedRuntimeException (com.b2international.commons.exceptions.FormattedRuntimeException)2 Aggregation (com.b2international.index.aggregations.Aggregation)2 Bucket (com.b2international.index.aggregations.Bucket)2 EsQueryBuilder (com.b2international.index.es.query.EsQueryBuilder)2 Expressions (com.b2international.index.query.Expressions)2 Query (com.b2international.index.query.Query)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 com.google.common.collect (com.google.common.collect)2 Lists.newArrayList (com.google.common.collect.Lists.newArrayList)2 java.util (java.util)2 ElasticsearchStatusException (org.elasticsearch.ElasticsearchStatusException)2 SearchRequest (org.elasticsearch.action.search.SearchRequest)2 SearchResponse (org.elasticsearch.action.search.SearchResponse)2