Search in sources :

Example 6 with Path

use of org.immutables.criteria.expression.Path in project immutables by immutables.

the class AggregateQueryBuilder method jsonQuery.

ObjectNode jsonQuery() {
    if (!query.groupBy().isEmpty() && query.offset().isPresent()) {
        String message = "Currently ES doesn't support generic pagination " + "with aggregations. You can still use LIMIT keyword (without OFFSET). " + "For more details see https://github.com/elastic/elasticsearch/issues/4915";
        throw new UnsupportedOperationException(message);
    }
    final ObjectNode json = nodeFactory.objectNode();
    json.put("_source", false);
    json.put("size", 0);
    // avoid fetch phase
    json.put("stored_fields", "_none_");
    query.filter().ifPresent(f -> json.set("query", Elasticsearch.constantScoreQuery(mapper, pathNaming, idPredicate).convert(f)));
    // due to ES aggregation format. fields in "order by" clause should go first
    // if "order by" is missing. order in "group by" is un-important
    final Set<Expression> orderedGroupBy = new LinkedHashSet<>();
    orderedGroupBy.addAll(query.collations().stream().map(Collation::expression).collect(Collectors.toList()));
    orderedGroupBy.addAll(query.groupBy());
    // construct nested aggregations node(s)
    ObjectNode parent = json.with(AGGREGATIONS);
    for (Expression expr : orderedGroupBy) {
        final String name = ((Path) expr).toStringPath();
        final String aggName = naming.apply(expr);
        final ObjectNode section = parent.with(aggName);
        final ObjectNode terms = section.with("terms");
        terms.put("field", name);
        mapping.missingValueFor(name).ifPresent(m -> {
            // expose missing terms. each type has a different missing value
            terms.set("missing", m);
        });
        query.limit().ifPresent(limit -> terms.put("size", limit));
        query.collations().stream().filter(c -> c.path().toStringPath().equals(name)).findAny().ifPresent(col -> terms.with("order").put("_key", col.direction().isAscending() ? "asc" : "desc"));
        parent = section.with(AGGREGATIONS);
    }
    for (Expression expr : query.projections()) {
        if (Visitors.isAggregationCall(expr)) {
            Call call = Visitors.toCall(expr);
            ObjectNode agg = nodeFactory.objectNode();
            String field = ((Path) call.arguments().get(0)).toStringPath();
            agg.with(toElasticAggregate(call)).put("field", field);
            parent.set(naming.apply(call), agg);
        }
    }
    // cleanup json. remove empty "aggregations" element (if empty)
    removeEmptyAggregation(json);
    return json;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Path(org.immutables.criteria.expression.Path) Call(org.immutables.criteria.expression.Call) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Expression(org.immutables.criteria.expression.Expression) Collation(org.immutables.criteria.expression.Collation)

Example 7 with Path

use of org.immutables.criteria.expression.Path in project immutables by immutables.

the class Elasticsearch method idPredicate.

/**
 * Predicate which checks if a path represents entity key (id). Used to generate {@code ids}
 * type of queries.
 */
static Predicate<Path> idPredicate(KeyExtractor.KeyMetadata metadata) {
    Objects.requireNonNull(metadata, "metadata");
    Predicate<Path> alwaysFalse = p -> false;
    if (!(metadata.isKeyDefined() && metadata.isExpression())) {
        return alwaysFalse;
    }
    if (metadata.keys().size() != 1) {
        return alwaysFalse;
    }
    Expression expression = Iterables.getOnlyElement(metadata.keys());
    return Visitors.maybePath(expression).map(p -> ((Predicate<Path>) p::equals)).orElse(alwaysFalse);
}
Also used : Path(org.immutables.criteria.expression.Path) Objects(java.util.Objects) KeyExtractor(org.immutables.criteria.backend.KeyExtractor) Iterables(com.google.common.collect.Iterables) Visitors(org.immutables.criteria.expression.Visitors) Path(org.immutables.criteria.expression.Path) ExpressionConverter(org.immutables.criteria.expression.ExpressionConverter) PathNaming(org.immutables.criteria.backend.PathNaming) Predicate(java.util.function.Predicate) Expression(org.immutables.criteria.expression.Expression) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Expression(org.immutables.criteria.expression.Expression)

Example 8 with Path

use of org.immutables.criteria.expression.Path in project immutables by immutables.

the class CriteriaContext method appendPath.

/**
 *  adds an intermediate path to partial expression
 */
public <T> CriteriaContext appendPath(Class<?> type, String pathAsString, CriteriaCreator<T> creator) {
    final Member member = memberLookup.find(type, pathAsString).orElseThrow(() -> new IllegalArgumentException(String.format("Path %s not found in %s", pathAsString, type)));
    Path newPath;
    Expression partial = state.partial();
    if (partial == null) {
        newPath = Path.ofMember(member);
    } else if (partial instanceof Path) {
        newPath = Visitors.toPath(partial).append(member);
    } else {
        throw new IllegalStateException("Partial expression is not a path: " + partial);
    }
    return new CriteriaContext(this, state.withPartial(newPath).withCreator(creator));
}
Also used : Path(org.immutables.criteria.expression.Path) Expression(org.immutables.criteria.expression.Expression) Member(java.lang.reflect.Member)

Example 9 with Path

use of org.immutables.criteria.expression.Path in project immutables by immutables.

the class CriteriaContext method any.

/**
 * Build {@link IterableMatcher#any()} sub-matcher.
 */
public CriteriaContext any() {
    Path path = path();
    // new path starts at this root
    Class<?> newType;
    try {
        newType = (Class<?>) Matchers.iterableTypeArgument(path.returnType());
    } catch (IllegalArgumentException | ClassCastException e) {
        throw new IllegalArgumentException(String.format("At path %s for %s", path.toStringPath(), path.returnType()), e);
    }
    Path newPath = Path.ofClass(newType);
    Combiner combiner = ((left, right) -> Expressions.binaryCall(IterableOperators.ANY, path, right));
    return new CriteriaContext(previous, state.withCombiner(combiner).withPartial(newPath));
}
Also used : Path(org.immutables.criteria.expression.Path)

Example 10 with Path

use of org.immutables.criteria.expression.Path in project immutables by immutables.

the class MatchersTest method projection.

@Test
void projection() {
    Expression expr1 = Matchers.toExpression(PersonCriteria.person.fullName);
    check(expr1 instanceof Path);
    check(((Path) expr1).toStringPath()).is("fullName");
    Expression expr2 = Matchers.toExpression(PersonCriteria.person.bestFriend.value().hobby);
    check(expr2 instanceof Path);
    check(((Path) expr2).toStringPath()).is("bestFriend.hobby");
}
Also used : Path(org.immutables.criteria.expression.Path) Expression(org.immutables.criteria.expression.Expression) Test(org.junit.jupiter.api.Test)

Aggregations

Path (org.immutables.criteria.expression.Path)15 Expression (org.immutables.criteria.expression.Expression)8 BsonDocument (org.bson.BsonDocument)5 ProjectedTuple (org.immutables.criteria.backend.ProjectedTuple)5 Query (org.immutables.criteria.expression.Query)5 Iterables (com.google.common.collect.Iterables)3 Objects (java.util.Objects)3 Optional (java.util.Optional)3 BsonString (org.bson.BsonString)3 Test (org.junit.jupiter.api.Test)3 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2 MongoException (com.mongodb.MongoException)2 BulkWriteResult (com.mongodb.bulk.BulkWriteResult)2 Projections (com.mongodb.client.model.Projections)2 ReplaceOneModel (com.mongodb.client.model.ReplaceOneModel)2 ReplaceOptions (com.mongodb.client.model.ReplaceOptions)2 Sorts (com.mongodb.client.model.Sorts)2 FullDocument (com.mongodb.client.model.changestream.FullDocument)2 ChangeStreamPublisher (com.mongodb.reactivestreams.client.ChangeStreamPublisher)2 FindPublisher (com.mongodb.reactivestreams.client.FindPublisher)2