Query methods
Queries using ArangoDB Query Language (AQL)
can be supplied with the @Query
annotation on methods.
Passing collection name
Instead of writing the collection name statically into the query string, the placeholder #collection
can be specified.
public interface MyRepository extends ArangoRepository<Customer, String>{
// FOR c IN customer RETURN c
@Query("FOR c IN #collection RETURN c")
ArangoCursor<Customer> query();
}
Passing bind parameters
There are three ways of passing bind parameters to the query in the query annotation.
Number matching
Using number matching, arguments will be substituted into the query in the order they are passed to the query method.
public interface MyRepository extends ArangoRepository<Customer, String>{
@Query("FOR c IN #collection FILTER c.name == @0 AND c.surname == @1 RETURN c")
ArangoCursor<Customer> query(String name, String surname);
}
@Param
With the @Param
annotation, the argument will be placed in the query at the place corresponding to the value passed to the @Param
annotation.
public interface MyRepository extends ArangoRepository<Customer, String>{
@Query("FOR c IN #collection FILTER c.name == @name AND c.surname == @surname RETURN c")
ArangoCursor<Customer> query(@Param("name") String name, @Param("surname") String surname);
}
@BindVars
In addition you can use a method parameter of type Map<String, Object>
annotated with @BindVars
as your bind parameters. You can then fill the map with any parameter used in the query (also see AQL Bind Parameters).
public interface MyRepository extends ArangoRepository<Customer, String>{
@Query("FOR c IN #collection FILTER c.name == @name AND c.surname = @surname RETURN c")
ArangoCursor<Customer> query(@BindVars Map<String, Object> bindVars);
}
A mixture of any of these methods can be used. Parameters with the same name from an @Param
annotation will override those in the bindVars
.
public interface MyRepository extends ArangoRepository<Customer, String>{
@Query("FOR c IN #collection FILTER c.name == @name AND c.surname = @surname RETURN c")
ArangoCursor<Customer> query(@BindVars Map<String, Object> bindVars, @Param("name") String name);
}
Query options
AqlQueryOptions
can also be passed to the driver, as an argument anywhere in the method signature.
public interface MyRepository extends ArangoRepository<Customer, String>{
@Query("FOR c IN #collection FILTER c.name == @name AND c.surname == @surname RETURN c")
ArangoCursor<Customer> query(@Param("name") String name, @Param("surname") String surname, AqlQueryOptions options);
}
Spring Expression support
SpEL expressions can be embedded in the query string to dynamically customize it depending on the invocation parameters and/or invoking methods on Spring Beans. In particular:
- SpEL expressions must be wrapped within
#{}
- SpEL variables can be set annotating method parameters with
@SpelParam("varName")
and referenced with#varName
- Spring Beans can be referenced with
@myBean
(factory beans with&myBean
) - the SpEL variable
#collection
is automatically set
public interface MyRepository extends ArangoRepository<Customer, String> {
@Query("FOR c IN #{#collection} FILTER #{@filterGenerator.allEqual('c', #kv)} RETURN c")
List<Customer> findByAllEqual(@SpelParam("kv") Map<String, Object> kv);
}
@Component("filterGenerator")
public class FilterGenerator {
public String allEqual(String col, Map<String, Object> kv) {
return kv.entrySet().stream()
.map(it -> col + "." + it.getKey() + " == " + escape(it.getValue()))
.collect(Collectors.joining(" AND "));
}
private Object escape(Object o) {
if (o instanceof String) return "\"" + o + "\"";
else return o;
}
}