Abstract
This chapter includes details of the Elasticsearch repository implementation.
The Spring Data Elasticsearch module contains a custom namespace
allowing
definition of repository beans as well as elements for
instantiating
a
ElasticsearchServer
.
Using the
repositories
element looks up Spring Data repositories as described in
Section 1.3.3, “Creating repository instances”
.
Example 2.1. Setting up Elasticsearch repositories using Namespace
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:repositories base-package="com.acme.repositories" /> </beans>
Using the
Transport Client
or
Node Client
element registers an instance of
Elasticsearch Server
in the context.
Example 2.2. Transport Client using Namespace
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" /> </beans>
Example 2.3. Node Client using Namespace
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:node-client id="client" local="true"" /> </beans>
The Spring Data Elasticsearch repositories support cannot only be activated through an XML namespace but also using an annotation through JavaConfig.
Example 2.4. Spring Data Elasticsearch repositories using JavaConfig
@Configuration @EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories") static class Config { @Bean public ElasticsearchOperations elasticsearchTemplate() { return new ElasticsearchTemplate(nodeBuilder().local(true).node().client()); } }
The configuration above sets up an
Embedded Elasticsearch Server
which is used by the
ElasticsearchTemplate
. Spring Data Elasticsearch Repositories are activated using the
@EnableElasticsearchRepositories
annotation, which
essentially carries the same attributes as the XML
namespace does. If no
base package is configured, it will use the
one
the configuration class
resides in.
The Spring Data Elasticsearch repositories can also be set up using CDI functionality.
Example 2.5. Spring Data Elasticsearch repositories using JavaConfig
class ElasticsearchTemplateProducer { @Produces @ApplicationScoped public ElasticsearchOperations createElasticsearchTemplate() { return new ElasticsearchTemplate(nodeBuilder().local(true).node().client()); } } class ProductService { private ProductRepository repository; public Page<Product> findAvailableBookByName(String name, Pageable pageable) { return repository.findByAvailableTrueAndNameStartingWith(name, pageable); } @Inject public void setRepository(ProductRepository repository) { this.repository = repository; } }
The Elasticsearch module supports all basic query building feature as String,Abstract,Criteria or have it being derived from the method name.
Deriving the query from the method name is not always sufficient
and/or may result in unreadable method names. In this case one
might make either use of
@Query
annotation (see
Section 2.2.3, “Using @Query Annotation”
).
Generally the query creation mechanism for Elasticsearch works as described in Section 1.3, “Query methods” . Here's a short example of what a Elasticsearch query method translates into:
Example 2.6. Query creation from method names
public interface BookRepository extends Repository<Book, String> { List<Book> findByNameAndPrice(String name, Integer price); }
The method name above will be translated into the following Elasticsearch json query
{ "bool" : { "must" : [ { "field" : {"name" : "?"} }, { "field" : {"price" : "?"} } ] } }
A list of supported keywords for Elasticsearch is shown below.
Table 2.1. Supported keywords inside method names
Keyword | Sample | Elasticsearch Query String |
---|---|---|
And
|
findByNameAndPrice
|
{"bool" : {"must" : [ {"field" : {"name" : "?"}},
{"field" : {"price" : "?"}} ]}}
|
Or
|
findByNameOrPrice
|
{"bool" : {"should" : [ {"field" : {"name" : "?"}},
{"field" : {"price" : "?"}} ]}}
|
Is
|
findByName
|
{"bool" : {"must" : {"field" : {"name" : "?"}}}}
|
Not
|
findByNameNot
|
{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
|
Between
|
findByPriceBetween
|
{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
|
LessThanEqual
|
findByPriceLessThan
|
{"bool" : {"must" : {"range" : {"price" : {"from" :
null,"to" : ?,"include_lower" : true,"include_upper" :
true}}}}}
|
GreaterThanEqual
|
findByPriceGreaterThan
|
{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : null,"include_lower" : true,"include_upper" :
true}}}}}
|
Before
|
findByPriceBefore
|
{"bool" : {"must" : {"range" : {"price" : {"from" :
null,"to" : ?,"include_lower" : true,"include_upper" :
true}}}}}
|
After
|
findByPriceAfter
|
{"bool" : {"must" : {"range" : {"price" : {"from" :
?,"to" : null,"include_lower" : true,"include_upper" :
true}}}}}
|
Like
|
findByNameLike
|
{"bool" : {"must" : {"field" : {"name" : {"query" :
"?*","analyze_wildcard" : true}}}}}
|
StartingWith
|
findByNameStartingWith
|
{"bool" : {"must" : {"field" : {"name" : {"query" :
"?*","analyze_wildcard" : true}}}}}
|
EndingWith
|
findByNameEndingWith
|
{"bool" : {"must" : {"field" : {"name" : {"query" :
"*?","analyze_wildcard" : true}}}}}
|
Contains/Containing
|
findByNameContaining
|
{"bool" : {"must" : {"field" : {"name" : {"query" :
"*?*","analyze_wildcard" : true}}}}}
|
In
|
findByNameIn(Collection<String>names)
|
{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
|
NotIn
|
findByNameNotIn(Collection<String>names)
|
{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
{"name" : "?"}}}}}}
|
Near
|
findByStoreNear
|
Not Supported Yet !
|
True
|
findByAvailableTrue
|
{"bool" : {"must" : {"field" : {"available" : true}}}}
|
False
|
findByAvailableFalse
|
{"bool" : {"must" : {"field" : {"available" : false}}}}
|
OrderBy
|
findByAvailableTrueOrderByNameDesc
|
{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
{"must" : {"field" : {"available" : true}}}}
|