@Override
 public <T> boolean putMapping(Class<T> clazz) {
   if (clazz.isAnnotationPresent(Mapping.class)) {
     String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
     if (isNotBlank(mappingPath)) {
       String mappings = readFileFromClasspath(mappingPath);
       if (isNotBlank(mappings)) {
         return putMapping(clazz, mappings);
       }
     } else {
       logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
     }
   }
   ElasticsearchPersistentEntity<T> persistentEntity = getPersistentEntityFor(clazz);
   XContentBuilder xContentBuilder = null;
   try {
     xContentBuilder =
         buildMapping(
             clazz,
             persistentEntity.getIndexType(),
             persistentEntity.getIdProperty().getFieldName(),
             persistentEntity.getParentType());
   } catch (Exception e) {
     throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
   }
   return putMapping(clazz, xContentBuilder);
 }
 private <T> Map getDefaultSettings(ElasticsearchPersistentEntity<T> persistentEntity) {
   return new MapBuilder<String, String>()
       .put("index.number_of_shards", String.valueOf(persistentEntity.getShards()))
       .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas()))
       .put("index.refresh_interval", persistentEntity.getRefreshInterval())
       .put("index.store.type", persistentEntity.getIndexStoreType())
       .map();
 }
 @Override
 public <T> void refresh(Class<T> clazz, boolean waitForOperation) {
   ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
   client
       .admin()
       .indices()
       .refresh(refreshRequest(persistentEntity.getIndexName()).force(waitForOperation))
       .actionGet();
 }
 @Override
 public <T> void delete(DeleteQuery deleteQuery, Class<T> clazz) {
   ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
   client
       .prepareDeleteByQuery(persistentEntity.getIndexName())
       .setTypes(persistentEntity.getIndexType())
       .setQuery(deleteQuery.getQuery())
       .execute()
       .actionGet();
 }
  @Override
  public <T> T queryForObject(GetQuery query, Class<T> clazz, GetResultMapper mapper) {
    ElasticsearchPersistentEntity<T> persistentEntity = getPersistentEntityFor(clazz);
    GetResponse response =
        client
            .prepareGet(
                persistentEntity.getIndexName(), persistentEntity.getIndexType(), query.getId())
            .execute()
            .actionGet();

    T entity = mapper.mapResult(response, clazz);
    return entity;
  }
  @Override
  public <T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz) {
    int startRecord = 0;
    ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
    String indexName =
        isNotBlank(query.getIndexName()) ? query.getIndexName() : persistentEntity.getIndexName();
    String type = isNotBlank(query.getType()) ? query.getType() : persistentEntity.getIndexType();

    Assert.notNull(indexName, "No 'indexName' defined for MoreLikeThisQuery");
    Assert.notNull(type, "No 'type' defined for MoreLikeThisQuery");
    Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery");

    MoreLikeThisRequestBuilder requestBuilder =
        client.prepareMoreLikeThis(indexName, type, query.getId());

    if (query.getPageable() != null) {
      startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
      requestBuilder.setSearchSize(query.getPageable().getPageSize());
    }
    requestBuilder.setSearchFrom(startRecord);

    if (isNotEmpty(query.getSearchIndices())) {
      requestBuilder.setSearchIndices(toArray(query.getSearchIndices()));
    }
    if (isNotEmpty(query.getSearchTypes())) {
      requestBuilder.setSearchTypes(toArray(query.getSearchTypes()));
    }
    if (isNotEmpty(query.getFields())) {
      requestBuilder.setField(toArray(query.getFields()));
    }
    if (isNotBlank(query.getRouting())) {
      requestBuilder.setRouting(query.getRouting());
    }
    if (query.getPercentTermsToMatch() != null) {
      requestBuilder.setPercentTermsToMatch(query.getPercentTermsToMatch());
    }
    if (query.getMinTermFreq() != null) {
      requestBuilder.setMinTermFreq(query.getMinTermFreq());
    }
    if (query.getMaxQueryTerms() != null) {
      requestBuilder.maxQueryTerms(query.getMaxQueryTerms());
    }
    if (isNotEmpty(query.getStopWords())) {
      requestBuilder.setStopWords(toArray(query.getStopWords()));
    }
    if (query.getMinDocFreq() != null) {
      requestBuilder.setMinDocFreq(query.getMinDocFreq());
    }
    if (query.getMaxDocFreq() != null) {
      requestBuilder.setMaxDocFreq(query.getMaxDocFreq());
    }
    if (query.getMinWordLen() != null) {
      requestBuilder.setMinWordLen(query.getMinWordLen());
    }
    if (query.getMaxWordLen() != null) {
      requestBuilder.setMaxWordLen(query.getMaxWordLen());
    }
    if (query.getBoostTerms() != null) {
      requestBuilder.setBoostTerms(query.getBoostTerms());
    }

    SearchResponse response = requestBuilder.execute().actionGet();
    return resultsMapper.mapResults(response, clazz, query.getPageable());
  }
 @Override
 public <T> String delete(Class<T> clazz, String id) {
   ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
   return delete(persistentEntity.getIndexName(), persistentEntity.getIndexType(), id);
 }