protected ExplainResponse shardOperation(ExplainRequest request, int shardId) throws ElasticSearchException { IndexService indexService = indicesService.indexService(request.index()); IndexShard indexShard = indexService.shardSafe(shardId); Term uidTerm = new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(request.getType(), request.getId())); Engine.GetResult result = indexShard.get(new Engine.Get(false, uidTerm)); if (!result.exists()) { return new ExplainResponse(false); } SearchContext context = new SearchContext( 0, new ShardSearchRequest() .types(new String[] {request.getType()}) .filteringAliases(request.getFilteringAlias()), null, result.searcher(), indexService, indexShard, scriptService); SearchContext.setCurrent(context); try { context.parsedQuery(parseQuery(request, indexService)); context.preProcess(); int topLevelDocId = result.docIdAndVersion().docId + result.docIdAndVersion().reader.docBase; Explanation explanation; if (context.rescore() != null) { RescoreSearchContext ctx = context.rescore(); Rescorer rescorer = ctx.rescorer(); explanation = rescorer.explain(topLevelDocId, context, ctx); } else { explanation = context.searcher().explain(context.query(), topLevelDocId); } if (request.getFields() != null) { if (request.getFields().length == 1 && "_source".equals(request.getFields()[0])) { request.setFields(null); // Load the _source field } // Advantage is that we're not opening a second searcher to retrieve the _source. Also // because we are working in the same searcher in engineGetResult we can be sure that a // doc isn't deleted between the initial get and this call. GetResult getResult = indexShard .getService() .get(result, request.getId(), request.getType(), request.getFields()); return new ExplainResponse(true, explanation, getResult); } else { return new ExplainResponse(true, explanation); } } catch (IOException e) { throw new ElasticSearchException("Could not explain", e); } finally { context.release(); SearchContext.removeCurrent(); } }
@Override protected ExplainResponse shardOperation(ExplainRequest request, ShardId shardId) throws ElasticsearchException { IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex()); IndexShard indexShard = indexService.shardSafe(shardId.id()); Term uidTerm = new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(request.type(), request.id())); Engine.GetResult result = indexShard.get(new Engine.Get(false, uidTerm)); if (!result.exists()) { return new ExplainResponse(shardId.getIndex(), request.type(), request.id(), false); } SearchContext context = new DefaultSearchContext( 0, new ShardSearchRequest(request) .types(new String[] {request.type()}) .filteringAliases(request.filteringAlias()) .nowInMillis(request.nowInMillis), null, result.searcher(), indexService, indexShard, scriptService, pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter()); SearchContext.setCurrent(context); try { context.parsedQuery(indexService.queryParserService().parseQuery(request.source())); context.preProcess(); int topLevelDocId = result.docIdAndVersion().docId + result.docIdAndVersion().context.docBase; Explanation explanation = context.searcher().explain(context.query(), topLevelDocId); for (RescoreSearchContext ctx : context.rescore()) { Rescorer rescorer = ctx.rescorer(); explanation = rescorer.explain(topLevelDocId, context, ctx, explanation); } if (request.fields() != null || (request.fetchSourceContext() != null && request.fetchSourceContext().fetchSource())) { // Advantage is that we're not opening a second searcher to retrieve the _source. Also // because we are working in the same searcher in engineGetResult we can be sure that a // doc isn't deleted between the initial get and this call. GetResult getResult = indexShard .getService() .get( result, request.id(), request.type(), request.fields(), request.fetchSourceContext(), false); return new ExplainResponse( shardId.getIndex(), request.type(), request.id(), true, explanation, getResult); } else { return new ExplainResponse( shardId.getIndex(), request.type(), request.id(), true, explanation); } } catch (IOException e) { throw new ElasticsearchException("Could not explain", e); } finally { context.close(); SearchContext.removeCurrent(); } }