private static JsonObject convertRemotePhraseQuery(RemotePhraseQuery query) {
    if (StringHelper.isEmpty(query.getPhrase())) {
      throw LOG.cannotQueryOnEmptyPhraseQuery();
    }

    JsonObject phraseQuery =
        JsonBuilder.object()
            .add(
                "match_phrase",
                JsonBuilder.object()
                    .add(
                        query.getField(),
                        JsonBuilder.object()
                            .addProperty("query", query.getPhrase().trim())
                            .addProperty(
                                "analyzer",
                                query
                                    .getAnalyzerReference()
                                    .getAnalyzer()
                                    .getName(query.getField()))
                            .addProperty("slop", query.getSlop())
                            .addProperty("boost", query.getBoost())))
            .build();

    return wrapQueryForNestedIfRequired(query.getField(), phraseQuery);
  }
  public static JsonObject fromLuceneQuery(Query query) {
    if (query instanceof MatchAllDocsQuery) {
      return convertMatchAllDocsQuery((MatchAllDocsQuery) query);
    } else if (query instanceof TermQuery) {
      return convertTermQuery((TermQuery) query);
    } else if (query instanceof BooleanQuery) {
      return convertBooleanQuery((BooleanQuery) query);
    } else if (query instanceof TermRangeQuery) {
      return convertTermRangeQuery((TermRangeQuery) query);
    } else if (query instanceof NumericRangeQuery) {
      return convertNumericRangeQuery((NumericRangeQuery<?>) query);
    } else if (query instanceof WildcardQuery) {
      return convertWildcardQuery((WildcardQuery) query);
    } else if (query instanceof FuzzyQuery) {
      return convertFuzzyQuery((FuzzyQuery) query);
    } else if (query instanceof RemotePhraseQuery) {
      return convertRemotePhraseQuery((RemotePhraseQuery) query);
    } else if (query instanceof RemoteMatchQuery) {
      return convertRemoteMatchQuery((RemoteMatchQuery) query);
    } else if (query instanceof ConstantScoreQuery) {
      return convertConstantScoreQuery((ConstantScoreQuery) query);
    } else if (query instanceof FilteredQuery) {
      return convertFilteredQuery((FilteredQuery) query);
    } else if (query instanceof Filter) {
      return fromLuceneFilter((Filter) query);
    } else if (query instanceof PhraseQuery) {
      return convertPhraseQuery((PhraseQuery) query);
    }

    throw LOG.cannotTransformLuceneQueryIntoEsQuery(query);
  }
  /**
   * This is best effort only: the PhraseQuery may contain multiple terms at the same position
   * (think synonyms) or gaps (think stopwords) and it's in this case impossible to translate it
   * into a correct ElasticsearchQuery.
   */
  private static JsonObject convertPhraseQuery(PhraseQuery query) {
    Term[] terms = query.getTerms();

    if (terms.length == 0) {
      throw LOG.cannotQueryOnEmptyPhraseQuery();
    }

    String field = terms[0].field(); // phrase queries are only supporting one field
    StringBuilder phrase = new StringBuilder();
    for (Term term : terms) {
      phrase.append(" ").append(term.text());
    }

    JsonObject phraseQuery =
        JsonBuilder.object()
            .add(
                "match_phrase",
                JsonBuilder.object()
                    .add(
                        field,
                        JsonBuilder.object()
                            .addProperty("query", phrase.toString().trim())
                            .addProperty("slop", query.getSlop())
                            .addProperty("boost", query.getBoost())))
            .build();

    return wrapQueryForNestedIfRequired(field, phraseQuery);
  }
 public static JsonObject fromLuceneFilter(Filter luceneFilter) {
   if (luceneFilter instanceof QueryWrapperFilter) {
     Query query = ((QueryWrapperFilter) luceneFilter).getQuery();
     query.setBoost(luceneFilter.getBoost() * query.getBoost());
     return fromLuceneQuery(query);
   } else if (luceneFilter instanceof DistanceFilter) {
     return convertDistanceFilter((DistanceFilter) luceneFilter);
   } else if (luceneFilter instanceof SpatialHashFilter) {
     return convertSpatialHashFilter((SpatialHashFilter) luceneFilter);
   } else if (luceneFilter instanceof CachingWrapperFilter) {
     return fromLuceneFilter(((CachingWrapperFilter) luceneFilter).getCachedFilter());
   }
   throw LOG.cannotTransformLuceneFilterIntoEsQuery(luceneFilter);
 }
 private static JsonObject fromFacetSortOrder(FacetSortOrder sortOrder) {
   JsonObject sort = new JsonObject();
   switch (sortOrder) {
     case COUNT_ASC:
       sort.addProperty("_count", "asc");
       break;
     case COUNT_DESC:
       sort.addProperty("_count", "desc");
       break;
     case FIELD_VALUE:
       sort.addProperty("_term", "asc");
       break;
     case RANGE_DEFINITION_ORDER:
       throw LOG.cannotSendRangeDefinitionOrderToElasticsearchBackend();
   }
   return sort;
 }