@Override
  public GetResult get(Get get, Function<String, Searcher> searcherFactory) throws EngineException {
    try (ReleasableLock lock = readLock.acquire()) {
      ensureOpen();
      if (get.realtime()) {
        VersionValue versionValue = versionMap.getUnderLock(get.uid().bytes());
        if (versionValue != null) {
          if (versionValue.delete()) {
            return GetResult.NOT_EXISTS;
          }
          if (get.versionType().isVersionConflictForReads(versionValue.version(), get.version())) {
            Uid uid = Uid.createUid(get.uid().text());
            throw new VersionConflictEngineException(
                shardId,
                uid.type(),
                uid.id(),
                get.versionType().explainConflictForReads(versionValue.version(), get.version()));
          }
          Translog.Operation op = translog.read(versionValue.translogLocation());
          if (op != null) {
            return new GetResult(true, versionValue.version(), op.getSource());
          }
        }
      }

      // no version, get the version from the index, we know that we refresh on flush
      return getFromSearcher(get, searcherFactory);
    }
  }
 @Override
 public void collect(int doc) {
   try {
     FieldsVisitor fieldsVisitor = new FieldsVisitor(false);
     context.reader().document(doc, fieldsVisitor);
     Uid uid = fieldsVisitor.uid();
     final long version =
         Versions.loadVersion(context.reader(), new Term(UidFieldMapper.NAME, uid.toBytesRef()));
     docsToPurge.add(new DocToPurge(uid.type(), uid.id(), version, fieldsVisitor.routing()));
   } catch (Exception e) {
     logger.trace("failed to collect doc", e);
   }
 }
 public void postProcess(MapperService mapperService) {
   if (uid != null) {
     DocumentMapper documentMapper = mapperService.documentMapper(uid.type());
     if (documentMapper != null) {
       // we can derive the exact type for the mapping
       postProcess(documentMapper);
       return;
     }
   }
   // can't derive exact mapping type
   for (Map.Entry<String, List<Object>> entry : fields().entrySet()) {
     FieldMappers fieldMappers = mapperService.indexName(entry.getKey());
     if (fieldMappers == null) {
       continue;
     }
     List<Object> fieldValues = entry.getValue();
     for (int i = 0; i < fieldValues.size(); i++) {
       fieldValues.set(i, fieldMappers.mapper().valueForSearch(fieldValues.get(i)));
     }
   }
 }