예제 #1
0
 private void loadQueries(IndexShard shard) {
   try {
     shard.refresh(new Engine.Refresh("percolator_load_queries").force(true));
     // Maybe add a mode load? This isn't really a write. We need write b/c state=post_recovery
     Engine.Searcher searcher =
         shard.acquireSearcher("percolator_load_queries", IndexShard.Mode.WRITE);
     try {
       Query query =
           new XConstantScoreQuery(
               indexCache
                   .filter()
                   .cache(
                       new TermFilter(
                           new Term(TypeFieldMapper.NAME, PercolatorService.TYPE_NAME))));
       QueriesLoaderCollector queryCollector =
           new QueriesLoaderCollector(
               PercolatorQueriesRegistry.this, logger, mapperService, indexFieldDataService);
       searcher.searcher().search(query, queryCollector);
       Map<HashedBytesRef, Query> queries = queryCollector.queries();
       for (Map.Entry<HashedBytesRef, Query> entry : queries.entrySet()) {
         Query previousQuery = percolateQueries.put(entry.getKey(), entry.getValue());
         shardPercolateService.addedQuery(entry.getKey(), previousQuery, entry.getValue());
       }
     } finally {
       searcher.release();
     }
   } catch (Exception e) {
     throw new PercolatorException(
         shardId.index(), "failed to load queries from percolator index", e);
   }
 }
예제 #2
0
 @Override
 protected ShardSuggestResponse shardOperation(ShardSuggestRequest request)
     throws ElasticSearchException {
   IndexService indexService = indicesService.indexServiceSafe(request.index());
   IndexShard indexShard = indexService.shardSafe(request.shardId());
   final Engine.Searcher searcher = indexShard.searcher();
   XContentParser parser = null;
   try {
     BytesReference suggest = request.suggest();
     if (suggest != null && suggest.length() > 0) {
       parser = XContentFactory.xContent(suggest).createParser(suggest);
       if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
         throw new ElasticSearchIllegalArgumentException("suggest content missing");
       }
       final SuggestionSearchContext context =
           suggestPhase
               .parseElement()
               .parseInternal(
                   parser, indexService.mapperService(), request.index(), request.shardId());
       final Suggest result = suggestPhase.execute(context, searcher.reader());
       return new ShardSuggestResponse(request.index(), request.shardId(), result);
     }
     return new ShardSuggestResponse(request.index(), request.shardId(), new Suggest());
   } catch (Throwable ex) {
     throw new ElasticSearchException("failed to execute suggest", ex);
   } finally {
     searcher.release();
     if (parser != null) {
       parser.close();
     }
   }
 }
  public void run() throws Exception {
    for (Thread t : searcherThreads) {
      t.start();
    }
    for (Thread t : writerThreads) {
      t.start();
    }
    barrier1.await();

    Refresher refresher = new Refresher();
    scheduledExecutorService.scheduleWithFixedDelay(
        refresher, refreshSchedule.millis(), refreshSchedule.millis(), TimeUnit.MILLISECONDS);
    Flusher flusher = new Flusher();
    scheduledExecutorService.scheduleWithFixedDelay(
        flusher, flushSchedule.millis(), flushSchedule.millis(), TimeUnit.MILLISECONDS);

    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    barrier2.await();

    latch.await();
    stopWatch.stop();

    System.out.println("Summary");
    System.out.println(
        "   -- Readers ["
            + searcherThreads.length
            + "] with ["
            + searcherIterations
            + "] iterations");
    System.out.println(
        "   -- Writers [" + writerThreads.length + "] with [" + writerIterations + "] iterations");
    System.out.println("   -- Took: " + stopWatch.totalTime());
    System.out.println(
        "   -- Refresh [" + refresher.id + "] took: " + refresher.stopWatch.totalTime());
    System.out.println("   -- Flush [" + flusher.id + "] took: " + flusher.stopWatch.totalTime());
    System.out.println("   -- Store size " + store.estimateSize());

    scheduledExecutorService.shutdown();

    engine.refresh(new Engine.Refresh(true));
    stopWatch = new StopWatch();
    stopWatch.start();
    Engine.Searcher searcher = engine.searcher();
    TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), idGenerator.get() + 1);
    stopWatch.stop();
    System.out.println(
        "   -- Indexed ["
            + idGenerator.get()
            + "] docs, found ["
            + topDocs.totalHits
            + "] hits, took "
            + stopWatch.totalTime());
    searcher.release();
  }
예제 #4
0
 @Override
 public PercolateShardResponse doPercolate(
     PercolateShardRequest request, PercolateContext context) {
   long count = 0;
   Engine.Searcher percolatorSearcher = context.indexShard().acquireSearcher("percolate");
   try {
     Count countCollector = count(logger, context);
     queryBasedPercolating(percolatorSearcher, context, countCollector);
     count = countCollector.counter();
   } catch (Throwable e) {
     logger.warn("failed to execute", e);
   } finally {
     percolatorSearcher.release();
   }
   return new PercolateShardResponse(count, context, request.index(), request.shardId());
 }
예제 #5
0
 private void loadQueries(String indexName) {
   IndexService indexService = percolatorIndexService();
   IndexShard shard = indexService.shard(0);
   Engine.Searcher searcher = shard.searcher();
   try {
     // create a query to fetch all queries that are registered under the index name (which is the
     // type
     // in the percolator).
     Query query = new DeletionAwareConstantScoreQuery(indexQueriesFilter(indexName));
     QueriesLoaderCollector queries = new QueriesLoaderCollector();
     searcher.searcher().search(query, queries);
     percolator.addQueries(queries.queries());
   } catch (IOException e) {
     throw new PercolatorException(index, "failed to load queries from percolator index");
   } finally {
     searcher.release();
   }
 }
 @Override
 public void run() {
   try {
     barrier1.await();
     barrier2.await();
     for (int i = 0; i < searcherIterations; i++) {
       Engine.Searcher searcher = engine.searcher();
       TopDocs topDocs =
           searcher.searcher().search(new TermQuery(new Term("content", content(i))), 10);
       // read one
       searcher.searcher().doc(topDocs.scoreDocs[0].doc, new LoadFirstFieldSelector());
       searcher.release();
     }
   } catch (Exception e) {
     System.out.println("Searcher thread failed");
     e.printStackTrace();
   } finally {
     latch.countDown();
   }
 }
예제 #7
0
        @Override
        public PercolateShardResponse doPercolate(
            PercolateShardRequest request, PercolateContext context) {
          Engine.Searcher percolatorSearcher = context.indexShard().acquireSearcher("percolate");
          try {
            Match match = match(logger, context, highlightPhase);
            queryBasedPercolating(percolatorSearcher, context, match);
            List<BytesRef> matches = match.matches();
            List<Map<String, HighlightField>> hls = match.hls();
            long count = match.counter();

            BytesRef[] finalMatches = matches.toArray(new BytesRef[matches.size()]);
            return new PercolateShardResponse(
                finalMatches, hls, count, context, request.index(), request.shardId());
          } catch (Throwable e) {
            logger.debug("failed to execute", e);
            throw new PercolateException(context.indexShard().shardId(), "failed to execute", e);
          } finally {
            percolatorSearcher.release();
          }
        }
예제 #8
0
 @Override
 public boolean release() throws ElasticSearchException {
   if (scanContext != null) {
     scanContext.clear();
   }
   // clear and scope phase we  have
   if (scopePhases != null) {
     for (ScopePhase scopePhase : scopePhases) {
       scopePhase.clear();
     }
   }
   // we should close this searcher, since its a new one we create each time, and we use the
   // IndexReader
   try {
     searcher.close();
   } catch (Exception e) {
     // ignore any exception here
   }
   engineSearcher.release();
   return true;
 }
예제 #9
0
        @Override
        public PercolateShardResponse doPercolate(
            PercolateShardRequest request, PercolateContext context) {
          Engine.Searcher percolatorSearcher = context.indexShard().acquireSearcher("percolate");
          try {
            MatchAndSort matchAndSort = QueryCollector.matchAndSort(logger, context);
            queryBasedPercolating(percolatorSearcher, context, matchAndSort);
            TopDocs topDocs = matchAndSort.topDocs();
            long count = topDocs.totalHits;
            List<BytesRef> matches = new ArrayList<BytesRef>(topDocs.scoreDocs.length);
            float[] scores = new float[topDocs.scoreDocs.length];
            List<Map<String, HighlightField>> hls = null;
            if (context.highlight() != null) {
              hls = new ArrayList<Map<String, HighlightField>>(topDocs.scoreDocs.length);
            }

            final FieldMapper<?> idMapper =
                context.mapperService().smartNameFieldMapper(IdFieldMapper.NAME);
            final IndexFieldData<?> idFieldData = context.fieldData().getForField(idMapper);
            int i = 0;
            final HashedBytesRef spare = new HashedBytesRef(new BytesRef());
            for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
              int segmentIdx =
                  ReaderUtil.subIndex(scoreDoc.doc, percolatorSearcher.reader().leaves());
              AtomicReaderContext atomicReaderContext =
                  percolatorSearcher.reader().leaves().get(segmentIdx);
              BytesValues values = idFieldData.load(atomicReaderContext).getBytesValues(true);
              final int localDocId = scoreDoc.doc - atomicReaderContext.docBase;
              final int numValues = values.setDocument(localDocId);
              assert numValues == 1;
              spare.bytes = values.nextValue();
              spare.hash = values.currentValueHash();
              matches.add(values.copyShared());
              if (hls != null) {
                Query query = context.percolateQueries().get(spare);
                context.parsedQuery(new ParsedQuery(query, ImmutableMap.<String, Filter>of()));
                context.hitContext().cache().clear();
                highlightPhase.hitExecute(context, context.hitContext());
                hls.add(i, context.hitContext().hit().getHighlightFields());
              }
              scores[i++] = scoreDoc.score;
            }
            if (hls != null) {
              return new PercolateShardResponse(
                  matches.toArray(new BytesRef[matches.size()]),
                  hls,
                  count,
                  scores,
                  context,
                  request.index(),
                  request.shardId());
            } else {
              return new PercolateShardResponse(
                  matches.toArray(new BytesRef[matches.size()]),
                  count,
                  scores,
                  context,
                  request.index(),
                  request.shardId());
            }
          } catch (Throwable e) {
            logger.debug("failed to execute", e);
            throw new PercolateException(context.indexShard().shardId(), "failed to execute", e);
          } finally {
            percolatorSearcher.release();
          }
        }
  @Test
  public void testSearchResultRelease() throws Exception {
    Engine.Searcher searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    searchResult.release();

    // create a document
    ParsedDocument doc =
        testParsedDocument(
            "1",
            "1",
            "test",
            null,
            -1,
            -1,
            testDocumentWithTextField(),
            Lucene.STANDARD_ANALYZER,
            B_1,
            false);
    engine.create(new Engine.Create(null, newUid("1"), doc));

    // its not there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    searchResult.release();

    // refresh and it should be there
    engine.refresh(new Engine.Refresh(true));

    // now its there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    // don't release the search result yet...

    // delete, refresh and do a new search, it should not be there
    engine.delete(new Engine.Delete("test", "1", newUid("1")));
    engine.refresh(new Engine.Refresh(true));
    Engine.Searcher updateSearchResult = engine.searcher();
    MatcherAssert.assertThat(
        updateSearchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    updateSearchResult.release();

    // the non release search result should not see the deleted yet...
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    searchResult.release();
  }
  @Test
  public void testSimpleOperations() throws Exception {
    Engine.Searcher searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    searchResult.release();

    // create a document
    Document document = testDocumentWithTextField();
    document.add(
        new Field(SourceFieldMapper.NAME, B_1.toBytes(), SourceFieldMapper.Defaults.FIELD_TYPE));
    ParsedDocument doc =
        testParsedDocument(
            "1", "1", "test", null, -1, -1, document, Lucene.STANDARD_ANALYZER, B_1, false);
    engine.create(new Engine.Create(null, newUid("1"), doc));

    // its not there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    searchResult.release();

    // but, we can still get it (in realtime)
    Engine.GetResult getResult = engine.get(new Engine.Get(true, newUid("1")));
    assertThat(getResult.exists(), equalTo(true));
    assertThat(getResult.source().source.toBytesArray(), equalTo(B_1.toBytesArray()));
    assertThat(getResult.docIdAndVersion(), nullValue());

    // but, not there non realtime
    getResult = engine.get(new Engine.Get(false, newUid("1")));
    assertThat(getResult.exists(), equalTo(false));

    // refresh and it should be there
    engine.refresh(new Engine.Refresh(true));

    // now its there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    searchResult.release();

    // also in non realtime
    getResult = engine.get(new Engine.Get(false, newUid("1")));
    assertThat(getResult.exists(), equalTo(true));
    assertThat(getResult.docIdAndVersion(), notNullValue());

    // now do an update
    document = testDocument();
    document.add(new TextField("value", "test1", Field.Store.YES));
    document.add(
        new Field(SourceFieldMapper.NAME, B_2.toBytes(), SourceFieldMapper.Defaults.FIELD_TYPE));
    doc =
        testParsedDocument(
            "1", "1", "test", null, -1, -1, document, Lucene.STANDARD_ANALYZER, B_2, false);
    engine.index(new Engine.Index(null, newUid("1"), doc));

    // its not updated yet...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 0));
    searchResult.release();

    // but, we can still get it (in realtime)
    getResult = engine.get(new Engine.Get(true, newUid("1")));
    assertThat(getResult.exists(), equalTo(true));
    assertThat(getResult.source().source.toBytesArray(), equalTo(B_2.toBytesArray()));
    assertThat(getResult.docIdAndVersion(), nullValue());

    // refresh and it should be updated
    engine.refresh(new Engine.Refresh(true));

    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 1));
    searchResult.release();

    // now delete
    engine.delete(new Engine.Delete("test", "1", newUid("1")));

    // its not deleted yet
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 1));
    searchResult.release();

    // but, get should not see it (in realtime)
    getResult = engine.get(new Engine.Get(true, newUid("1")));
    assertThat(getResult.exists(), equalTo(false));

    // refresh and it should be deleted
    engine.refresh(new Engine.Refresh(true));

    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 0));
    searchResult.release();

    // add it back
    document = testDocumentWithTextField();
    document.add(
        new Field(SourceFieldMapper.NAME, B_1.toBytes(), SourceFieldMapper.Defaults.FIELD_TYPE));
    doc =
        testParsedDocument(
            "1", "1", "test", null, -1, -1, document, Lucene.STANDARD_ANALYZER, B_1, false);
    engine.create(new Engine.Create(null, newUid("1"), doc));

    // its not there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 0));
    searchResult.release();

    // refresh and it should be there
    engine.refresh(new Engine.Refresh(true));

    // now its there...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 0));
    searchResult.release();

    // now flush
    engine.flush(new Engine.Flush());

    // and, verify get (in real time)
    getResult = engine.get(new Engine.Get(true, newUid("1")));
    assertThat(getResult.exists(), equalTo(true));
    assertThat(getResult.source(), nullValue());
    assertThat(getResult.docIdAndVersion(), notNullValue());

    // make sure we can still work with the engine
    // now do an update
    document = testDocument();
    document.add(new TextField("value", "test1", Field.Store.YES));
    doc =
        testParsedDocument(
            "1", "1", "test", null, -1, -1, document, Lucene.STANDARD_ANALYZER, B_1, false);
    engine.index(new Engine.Index(null, newUid("1"), doc));

    // its not updated yet...
    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 0));
    searchResult.release();

    // refresh and it should be updated
    engine.refresh(new Engine.Refresh(true));

    searchResult = engine.searcher();
    MatcherAssert.assertThat(
        searchResult, EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(1));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test")), 0));
    MatcherAssert.assertThat(
        searchResult,
        EngineSearcherTotalHitsMatcher.engineSearcherTotalHits(
            new TermQuery(new Term("value", "test1")), 1));
    searchResult.release();

    engine.close();
  }
  @Override
  protected ShardStatus shardOperation(IndexShardStatusRequest request)
      throws ElasticSearchException {
    InternalIndexService indexService =
        (InternalIndexService) indicesService.indexServiceSafe(request.index());
    InternalIndexShard indexShard = (InternalIndexShard) indexService.shardSafe(request.shardId());
    ShardStatus shardStatus = new ShardStatus(indexShard.routingEntry());
    shardStatus.state = indexShard.state();
    try {
      shardStatus.storeSize = indexShard.store().estimateSize();
    } catch (IOException e) {
      // failure to get the store size...
    }
    if (indexShard.state() == IndexShardState.STARTED) {
      //            shardStatus.estimatedFlushableMemorySize =
      // indexShard.estimateFlushableMemorySize();
      shardStatus.translogId = indexShard.translog().currentId();
      shardStatus.translogOperations = indexShard.translog().estimatedNumberOfOperations();
      Engine.Searcher searcher = indexShard.searcher();
      try {
        shardStatus.docs = new DocsStatus();
        shardStatus.docs.numDocs = searcher.reader().numDocs();
        shardStatus.docs.maxDoc = searcher.reader().maxDoc();
        shardStatus.docs.deletedDocs = searcher.reader().numDeletedDocs();
      } finally {
        searcher.release();
      }

      shardStatus.mergeStats = indexShard.mergeScheduler().stats();
      shardStatus.refreshStats = indexShard.refreshStats();
      shardStatus.flushStats = indexShard.flushStats();
    }

    if (request.recovery) {
      // check on going recovery (from peer or gateway)
      RecoveryStatus peerRecoveryStatus = indexShard.peerRecoveryStatus();
      if (peerRecoveryStatus == null) {
        peerRecoveryStatus = peerRecoveryTarget.peerRecoveryStatus(indexShard.shardId());
      }
      if (peerRecoveryStatus != null) {
        PeerRecoveryStatus.Stage stage;
        switch (peerRecoveryStatus.stage()) {
          case INIT:
            stage = PeerRecoveryStatus.Stage.INIT;
            break;
          case INDEX:
            stage = PeerRecoveryStatus.Stage.INDEX;
            break;
          case TRANSLOG:
            stage = PeerRecoveryStatus.Stage.TRANSLOG;
            break;
          case FINALIZE:
            stage = PeerRecoveryStatus.Stage.FINALIZE;
            break;
          case DONE:
            stage = PeerRecoveryStatus.Stage.DONE;
            break;
          default:
            stage = PeerRecoveryStatus.Stage.INIT;
        }
        shardStatus.peerRecoveryStatus =
            new PeerRecoveryStatus(
                stage,
                peerRecoveryStatus.startTime(),
                peerRecoveryStatus.time(),
                peerRecoveryStatus.phase1TotalSize(),
                peerRecoveryStatus.phase1ExistingTotalSize(),
                peerRecoveryStatus.currentFilesSize(),
                peerRecoveryStatus.currentTranslogOperations());
      }

      IndexShardGatewayService gatewayService =
          indexService.shardInjector(request.shardId()).getInstance(IndexShardGatewayService.class);
      org.elasticsearch.index.gateway.RecoveryStatus gatewayRecoveryStatus =
          gatewayService.recoveryStatus();
      if (gatewayRecoveryStatus != null) {
        GatewayRecoveryStatus.Stage stage;
        switch (gatewayRecoveryStatus.stage()) {
          case INIT:
            stage = GatewayRecoveryStatus.Stage.INIT;
            break;
          case INDEX:
            stage = GatewayRecoveryStatus.Stage.INDEX;
            break;
          case TRANSLOG:
            stage = GatewayRecoveryStatus.Stage.TRANSLOG;
            break;
          case DONE:
            stage = GatewayRecoveryStatus.Stage.DONE;
            break;
          default:
            stage = GatewayRecoveryStatus.Stage.INIT;
        }
        shardStatus.gatewayRecoveryStatus =
            new GatewayRecoveryStatus(
                stage,
                gatewayRecoveryStatus.startTime(),
                gatewayRecoveryStatus.time(),
                gatewayRecoveryStatus.index().totalSize(),
                gatewayRecoveryStatus.index().reusedTotalSize(),
                gatewayRecoveryStatus.index().currentFilesSize(),
                gatewayRecoveryStatus.translog().currentTranslogOperations());
      }
    }

    if (request.snapshot) {
      IndexShardGatewayService gatewayService =
          indexService.shardInjector(request.shardId()).getInstance(IndexShardGatewayService.class);
      SnapshotStatus snapshotStatus = gatewayService.snapshotStatus();
      if (snapshotStatus != null) {
        GatewaySnapshotStatus.Stage stage;
        switch (snapshotStatus.stage()) {
          case DONE:
            stage = GatewaySnapshotStatus.Stage.DONE;
            break;
          case FAILURE:
            stage = GatewaySnapshotStatus.Stage.FAILURE;
            break;
          case TRANSLOG:
            stage = GatewaySnapshotStatus.Stage.TRANSLOG;
            break;
          case FINALIZE:
            stage = GatewaySnapshotStatus.Stage.FINALIZE;
            break;
          case INDEX:
            stage = GatewaySnapshotStatus.Stage.INDEX;
            break;
          default:
            stage = GatewaySnapshotStatus.Stage.NONE;
            break;
        }
        shardStatus.gatewaySnapshotStatus =
            new GatewaySnapshotStatus(
                stage,
                snapshotStatus.startTime(),
                snapshotStatus.time(),
                snapshotStatus.index().totalSize(),
                snapshotStatus.translog().expectedNumberOfOperations());
      }
    }

    return shardStatus;
  }
  @Override
  protected GetResponse shardOperation(GetRequest request, int shardId)
      throws ElasticSearchException {
    IndexService indexService = indicesService.indexServiceSafe(request.index());
    BloomCache bloomCache = indexService.cache().bloomCache();
    IndexShard indexShard = indexService.shardSafe(shardId);

    DocumentMapper docMapper = indexService.mapperService().documentMapper(request.type());
    if (docMapper == null) {
      throw new TypeMissingException(new Index(request.index()), request.type());
    }

    if (request.refresh()) {
      indexShard.refresh(new Engine.Refresh(false));
    }

    Engine.Searcher searcher = indexShard.searcher();
    boolean exists = false;
    byte[] source = null;
    Map<String, GetField> fields = null;
    long version = -1;
    try {
      UidField.DocIdAndVersion docIdAndVersion =
          loadCurrentVersionFromIndex(
              bloomCache, searcher, docMapper.uidMapper().term(request.type(), request.id()));
      if (docIdAndVersion != null && docIdAndVersion.docId != Lucene.NO_DOC) {
        if (docIdAndVersion.version > 0) {
          version = docIdAndVersion.version;
        }
        exists = true;
        FieldSelector fieldSelector = buildFieldSelectors(docMapper, request.fields());
        if (fieldSelector != null) {
          Document doc = docIdAndVersion.reader.document(docIdAndVersion.docId, fieldSelector);
          source = extractSource(doc, docMapper);

          for (Object oField : doc.getFields()) {
            Fieldable field = (Fieldable) oField;
            String name = field.name();
            Object value = null;
            FieldMappers fieldMappers = docMapper.mappers().indexName(field.name());
            if (fieldMappers != null) {
              FieldMapper mapper = fieldMappers.mapper();
              if (mapper != null) {
                name = mapper.names().fullName();
                value = mapper.valueForSearch(field);
              }
            }
            if (value == null) {
              if (field.isBinary()) {
                value = field.getBinaryValue();
              } else {
                value = field.stringValue();
              }
            }

            if (fields == null) {
              fields = newHashMapWithExpectedSize(2);
            }

            GetField getField = fields.get(name);
            if (getField == null) {
              getField = new GetField(name, new ArrayList<Object>(2));
              fields.put(name, getField);
            }
            getField.values().add(value);
          }
        }

        // now, go and do the script thingy if needed
        if (request.fields() != null && request.fields().length > 0) {
          SearchLookup searchLookup = null;
          for (String field : request.fields()) {
            String script = null;
            if (field.contains("_source.") || field.contains("doc[")) {
              script = field;
            } else {
              FieldMappers x = docMapper.mappers().smartName(field);
              if (x != null && !x.mapper().stored()) {
                script = "_source." + x.mapper().names().fullName();
              }
            }
            if (script != null) {
              if (searchLookup == null) {
                searchLookup =
                    new SearchLookup(
                        indexService.mapperService(), indexService.cache().fieldData());
              }
              SearchScript searchScript = scriptService.search(searchLookup, "mvel", script, null);
              searchScript.setNextReader(docIdAndVersion.reader);
              searchScript.setNextDocId(docIdAndVersion.docId);

              try {
                Object value = searchScript.run();
                if (fields == null) {
                  fields = newHashMapWithExpectedSize(2);
                }
                GetField getField = fields.get(field);
                if (getField == null) {
                  getField = new GetField(field, new ArrayList<Object>(2));
                  fields.put(field, getField);
                }
                getField.values().add(value);
              } catch (RuntimeException e) {
                if (logger.isTraceEnabled()) {
                  logger.trace("failed to execute get request script field [{}]", e, script);
                }
                // ignore
              }
            }
          }
        }
      }
    } catch (IOException e) {
      throw new ElasticSearchException(
          "Failed to get type [" + request.type() + "] and id [" + request.id() + "]", e);
    } finally {
      searcher.release();
    }
    return new GetResponse(
        request.index(), request.type(), request.id(), version, exists, source, fields);
  }