private Flowable<?> select(StandardOperations.Select op) {
      final Query query = op.query();

      if (query.distinct()) {
        return Flowable.error(new UnsupportedOperationException("DISTINCT not yet supported by " + ElasticsearchBackend.class.getSimpleName()));
      }

      if (query.count()) {
        return new CountCall(op, this).call().toFlowable();
      }

      if (query.hasAggregations()) {
        return aggregate(op);
      }
      final ObjectNode json = objectMapper.createObjectNode();

      query.filter().ifPresent(f -> json.set("query", Elasticsearch.constantScoreQuery(objectMapper, pathNaming, idPredicate).convert(f)));
      query.limit().ifPresent(limit -> json.put("size", limit));
      query.offset().ifPresent(offset -> json.put("from", offset));
      if (!query.collations().isEmpty()) {
        final ArrayNode sort = json.withArray("sort");
        query.collations().forEach(c -> {
          sort.add(objectMapper.createObjectNode().put(c.path().toStringPath(), c.direction().isAscending() ? "asc" : "desc"));
        });
      }

      JsonConverter converter = this.converter;

      if (query.hasProjections()) {
        ArrayNode projection = query.projections().stream()
                 .map(p -> ((Path) p).toStringPath())
                 .reduce(objectMapper.createArrayNode(), ArrayNode::add, (old, newNode) -> newNode);
        json.set("_source", projection);
        converter = new ToTupleConverter(query, objectMapper);
      }

      final Flowable<?> flowable;
      if (query.offset().isPresent()) {
        // scroll doesn't work with offset
        flowable = ops.search(json, (JsonConverter<?>) converter);
      } else {
        flowable = ops.scrolledSearch(json, (JsonConverter<?>) converter);
      }

      return flowable;
    }
Queries <a href="https://www.elastic.co/">ElasticSearch</a> data-store.
criteria/elasticsearch/src/org/immutables/criteria/elasticsearch/ElasticsearchBackend.java