All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.percolator.TransportPercolateAction Maven / Gradle / Ivy

/*
 * 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.percolator;

import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ShardOperationFailedException;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Deprecated
public class TransportPercolateAction extends HandledTransportAction {

    private final Client client;
    private final NamedXContentRegistry xContentRegistry;

    @Inject
    public TransportPercolateAction(Settings settings, ThreadPool threadPool, TransportService transportService,
                                    ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
                                    Client client, NamedXContentRegistry xContentRegistry) {
        super(settings, PercolateAction.NAME, threadPool, transportService, actionFilters,
                indexNameExpressionResolver, PercolateRequest::new);
        this.client = client;
        this.xContentRegistry = xContentRegistry;
    }

    @Override
    protected void doExecute(PercolateRequest request, ActionListener listener) {
        if (request.getRequest() != null) {
            client.get(request.getRequest(), new ActionListener() {
                @Override
                public void onResponse(GetResponse getResponse) {
                    if (getResponse.isExists()) {
                        innerDoExecute(request, getResponse.getSourceAsBytesRef(), listener);
                    } else {
                        onFailure(new ResourceNotFoundException("percolate document [{}/{}/{}] doesn't exist",
                                request.getRequest().index(), request.getRequest().type(), request.getRequest().id()));
                    }
                }

                @Override
                public void onFailure(Exception e) {
                    listener.onFailure(e);
                }
            });
        } else {
            innerDoExecute(request, null, listener);
        }
    }

    private void innerDoExecute(PercolateRequest request, BytesReference docSource, ActionListener listener) {
        SearchRequest searchRequest;
        try {
            searchRequest = createSearchRequest(request, docSource, xContentRegistry);
        } catch (IOException e) {
            listener.onFailure(e);
            return;
        }
        client.search(searchRequest, new ActionListener() {
            @Override
            public void onResponse(SearchResponse searchResponse) {
                try {
                    listener.onResponse(createPercolateResponse(searchResponse, request.onlyCount()));
                } catch (Exception e) {
                    onFailure(e);
                }
            }

            @Override
            public void onFailure(Exception e) {
                listener.onFailure(e);
            }
        });
    }

    public static SearchRequest createSearchRequest(PercolateRequest percolateRequest, BytesReference documentSource,
                                                    NamedXContentRegistry xContentRegistry)
            throws IOException {
        SearchRequest searchRequest = new SearchRequest();
        if (percolateRequest.indices() != null) {
            searchRequest.indices(percolateRequest.indices());
        }
        searchRequest.indicesOptions(percolateRequest.indicesOptions());
        searchRequest.routing(percolateRequest.routing());
        searchRequest.preference(percolateRequest.preference());

        BytesReference querySource = null;
        XContentBuilder searchSource = XContentFactory.jsonBuilder().startObject();
        if (percolateRequest.source() != null && percolateRequest.source().length() > 0) {
            try (XContentParser parser = XContentHelper.createParser(xContentRegistry, percolateRequest.source())) {
                String currentFieldName = null;
                XContentParser.Token token = parser.nextToken();
                if (token != XContentParser.Token.START_OBJECT) {
                    throw new IllegalArgumentException("Unknown token [" + token+ "]");
                }

                while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                    if (token == XContentParser.Token.FIELD_NAME) {
                        currentFieldName = parser.currentName();
                    } else if (token == XContentParser.Token.START_OBJECT) {
                        if ("doc".equals(currentFieldName)) {
                            XContentBuilder builder = XContentFactory.jsonBuilder();
                            builder.copyCurrentStructure(parser);
                            builder.flush();
                            documentSource = builder.bytes();
                        } else if ("query".equals(currentFieldName) || "filter".equals(currentFieldName)) {
                            XContentBuilder builder = XContentFactory.jsonBuilder();
                            builder.copyCurrentStructure(parser);
                            builder.flush();
                            querySource = builder.bytes();
                        } else if ("sort".equals(currentFieldName)) {
                            searchSource.field("sort");
                            searchSource.copyCurrentStructure(parser);
                        } else if ("aggregations".equals(currentFieldName)) {
                            searchSource.field("aggregations");
                            searchSource.copyCurrentStructure(parser);
                        } else if ("highlight".equals(currentFieldName)) {
                            searchSource.field("highlight");
                            searchSource.copyCurrentStructure(parser);
                        } else {
                            throw new IllegalArgumentException("Unknown field [" + currentFieldName+ "]");
                        }
                    } else if (token == XContentParser.Token.START_ARRAY) {
                        if ("sort".equals(currentFieldName)) {
                            searchSource.field("sort");
                            searchSource.copyCurrentStructure(parser);
                        } else {
                            throw new IllegalArgumentException("Unknown field [" + currentFieldName+ "]");
                        }
                    } else if (token.isValue()) {
                        if ("size".equals(currentFieldName)) {
                            searchSource.field("size", parser.intValue());
                        } else if ("sort".equals(currentFieldName)) {
                            searchSource.field("sort", parser.text());
                        } else if ("track_scores".equals(currentFieldName) || "trackScores".equals(currentFieldName)) {
                            searchSource.field("track_scores", parser.booleanValue());
                        } else {
                            throw new IllegalArgumentException("Unknown field [" + currentFieldName+ "]");
                        }
                    } else {
                        throw new IllegalArgumentException("Unknown token [" + token + "]");
                    }
                }
            }
        }

        if (percolateRequest.onlyCount()) {
            searchSource.field("size", 0);
        }

        PercolateQueryBuilder percolateQueryBuilder =
                new PercolateQueryBuilder("query", percolateRequest.documentType(), documentSource);
        if (querySource != null) {
            try (XContentParser parser = XContentHelper.createParser(xContentRegistry, querySource)) {
                QueryParseContext queryParseContext = new QueryParseContext(parser);
                BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                queryParseContext.parseInnerQueryBuilder().ifPresent(boolQueryBuilder::must);
                boolQueryBuilder.filter(percolateQueryBuilder);
                searchSource.field("query", boolQueryBuilder);
            }
        } else {
            // wrapping in a constant score query with boost 0 for bwc reason.
            // percolator api didn't emit scores before and never included scores
            // for how well percolator queries matched with the document being percolated
            searchSource.field("query", new ConstantScoreQueryBuilder(percolateQueryBuilder).boost(0f));
        }

        searchSource.endObject();
        searchSource.flush();
        BytesReference source = searchSource.bytes();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContentRegistry, source)) {
            QueryParseContext context = new QueryParseContext(parser);
            searchSourceBuilder.parseXContent(context);
            searchRequest.source(searchSourceBuilder);
            return searchRequest;
        }
    }

    public static PercolateResponse createPercolateResponse(SearchResponse searchResponse, boolean onlyCount) {
        SearchHits hits = searchResponse.getHits();
        PercolateResponse.Match[] matches;
        if (onlyCount) {
            matches = null;
        } else {
            matches = new PercolateResponse.Match[hits.getHits().length];
            for (int i = 0; i < hits.getHits().length; i++) {
                SearchHit hit = hits.getHits()[i];
                matches[i] = new PercolateResponse.Match(new Text(hit.getIndex()),
                        new Text(hit.getId()), hit.getScore(), hit.getHighlightFields());
            }
        }

        List shardFailures = new ArrayList<>(searchResponse.getShardFailures().length);
        for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
            shardFailures.add(new DefaultShardOperationFailedException(shardSearchFailure.index(), shardSearchFailure.shardId(),
                    shardSearchFailure.getCause()));
        }

        return new PercolateResponse(
            searchResponse.getTotalShards(), searchResponse.getSuccessfulShards(), searchResponse.getFailedShards(), shardFailures,
                matches, hits.getTotalHits(), searchResponse.getTookInMillis(), (InternalAggregations) searchResponse.getAggregations()
        );
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy