Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cbb7cd172 | |||
| 3bb84212ae | |||
| 87c356b458 | |||
| 3e888bd08d | |||
| e5c7acf4f0 | |||
| 49848c7402 | |||
| 3f9fb01ace | |||
| 7ec291d572 | |||
| 0aab5f940f | |||
| eedcd8685f | |||
| 64d03e82fd | |||
| e07288e6e1 | |||
| 0d15936e7c | |||
| 6f60464035 | |||
| 584dba0b23 | |||
| d41a925779 | |||
| 28e3a8c7fb | |||
| d4fed726fa | |||
| 45495603d9 | |||
| f5bee25fc6 | |||
| 1af59690eb | |||
| 5e658a8069 | |||
| 8ee7570a97 | |||
| daebfd4f20 | |||
| 7591c46874 | |||
| f2a047aaaf | |||
| 95fc878c53 | |||
| 89730fe7b1 | |||
| 1ea9920a0d | |||
| c866664acc | |||
| 479a670e2f | |||
| 097c5f68ce | |||
| a66dc08975 | |||
| f17bb3ac18 | |||
| 594b4536a1 | |||
| 76952c7fc2 | |||
| 858ae6eb03 | |||
| b0513c2a8c | |||
| 31797fad6e | |||
| b77b8ba0f2 | |||
| 1f99dcb911 | |||
| 0317dcb275 | |||
| cf54ba4e8f | |||
| 705adf25f2 | |||
| a08a6fbde9 | |||
| 2bca32bb86 | |||
| 873dcca561 | |||
| a92af0e3e5 | |||
| fa5d1b1e49 | |||
| 6d61dceab9 | |||
| 5faf54b67c | |||
| cb7983120e | |||
| fd054138b4 | |||
| 6b998d2974 | |||
| 1b292a7001 | |||
| 24c12585c2 | |||
| 2f28a9c5c6 | |||
| 6b74c6b8da | |||
| 5a691986a1 | |||
| ab7e870d5f | |||
| 369b2eb969 | |||
| 222c479fb5 |
@@ -13,7 +13,7 @@ Guide
|
||||
* [Reference Documentation](http://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/)
|
||||
* [PDF Documentation](http://docs.spring.io/spring-data/elasticsearch/docs/current/reference/pdf/spring-data-elasticsearch-reference.pdf)
|
||||
* [API Documentation](http://docs.spring.io/spring-data/elasticsearch/docs/current/api/)
|
||||
* [Spring Data Project](http://project.spring.io/spring-data)
|
||||
* [Spring Data Project](http://projects.spring.io/spring-data)
|
||||
* [Sample Test Application](https://github.com/BioMedCentralLtd/spring-data-elasticsearch-sample-application)
|
||||
* [Spring Data Elasticsearch Google Group](https://groups.google.com/d/forum/spring-data-elasticsearch-devs)
|
||||
* For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80).
|
||||
@@ -52,6 +52,11 @@ the appropriate dependency version.
|
||||
</repository>
|
||||
```
|
||||
|
||||
###Note:
|
||||
Spring data elaticsearch 1.0.0.RELEASE version is on elasticsearch 1.1.1 library which uses java 1.6 or later version.
|
||||
As latest version of elasticsearch 1.2.x is now supporting java 1.7, future releases of spring data elasticsearch library can be used with Java 7 or later version.
|
||||
In order to use with java 6 it has to be with elasticsearch 1.1.x.
|
||||
|
||||
### ElasticsearchRepository
|
||||
A default implementation of ElasticsearchRepository, aligning to the generic Repository Interfaces, is provided. Spring can do the Repository implementation for you depending on method names in the interface definition.
|
||||
|
||||
@@ -239,4 +244,4 @@ Before we accept a non-trivial patch or pull request we will need you to sign th
|
||||
|
||||
Code formatting for [Eclipse and Intellij](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide)
|
||||
|
||||
[More information about contributing to Spring Data](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.md)
|
||||
[More information about contributing to Spring Data](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.md)
|
||||
|
||||
@@ -1,178 +1,182 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>1.1.3.RELEASE</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.5.3.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
<description>Spring Data Implementation for Elasticsearch</description>
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
<description>Spring Data Implementation for Elasticsearch</description>
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
|
||||
<properties>
|
||||
<properties>
|
||||
|
||||
<dist.key>DATAES</dist.key>
|
||||
<dist.key>DATAES</dist.key>
|
||||
|
||||
<commonscollections>3.2.1</commonscollections>
|
||||
<commonslang>2.6</commonslang>
|
||||
<elasticsearch>1.1.1</elasticsearch>
|
||||
<springdata.commons>1.8.0.RELEASE</springdata.commons>
|
||||
<commonscollections>3.2.1</commonscollections>
|
||||
<commonslang>2.6</commonslang>
|
||||
<elasticsearch>1.3.2</elasticsearch>
|
||||
<springdata.commons>1.9.3.RELEASE</springdata.commons>
|
||||
|
||||
</properties>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SPRING DATA -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>${springdata.commons}</version>
|
||||
</dependency>
|
||||
<!-- SPRING DATA -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>${springdata.commons}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- APACHE -->
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commonslang}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>${commonscollections}</version>
|
||||
</dependency>
|
||||
<!-- APACHE -->
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>${commonslang}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>${commonscollections}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JODA Time -->
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
</dependency>
|
||||
<!-- JODA Time -->
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Elasticsearch -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
<version>${elasticsearch}</version>
|
||||
</dependency>
|
||||
<!-- Elasticsearch -->
|
||||
<dependency>
|
||||
<groupId>org.elasticsearch</groupId>
|
||||
<artifactId>elasticsearch</artifactId>
|
||||
<version>${elasticsearch}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson JSON Mapper -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson}</version>
|
||||
</dependency>
|
||||
<!-- Jackson JSON Mapper -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CDI -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- CDI -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>3.0-alpha-1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>3.0-alpha-1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>biomedcentral</id>
|
||||
<name>BioMed Central Development Team</name>
|
||||
<timezone>+0</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>biomedcentral</id>
|
||||
<name>BioMed Central Development Team</name>
|
||||
<timezone>+0</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-release</id>
|
||||
<url>http://repo.spring.io/libs-release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-release</id>
|
||||
<url>https://repo.spring.io/libs-release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>http://repo.spring.io/plugins-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-plugins-release</id>
|
||||
<url>http://repo.spring.io/plugins-release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
<connection>scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git
|
||||
</developerConnection>
|
||||
</scm>
|
||||
<scm>
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
<connection>scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git
|
||||
</developerConnection>
|
||||
</scm>
|
||||
|
||||
<ciManagement>
|
||||
<system>Bamboo</system>
|
||||
<url>http://build.springsource.org/browse/SPRINGDATAES</url>
|
||||
</ciManagement>
|
||||
<ciManagement>
|
||||
<system>Bamboo</system>
|
||||
<url>http://build.springsource.org/browse/SPRINGDATAES</url>
|
||||
</ciManagement>
|
||||
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>https://jira.springsource.org/browse/DATAES</url>
|
||||
</issueManagement>
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>https://jira.springsource.org/browse/DATAES</url>
|
||||
</issueManagement>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<bookinfo>
|
||||
<title>Spring Data Elasticsearch</title>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>BioMed Central</firstname>
|
||||
<surname>Development Team</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<legalnotice>
|
||||
<para>
|
||||
Copies of this document may be made for your own use and for
|
||||
distribution to others, provided that you do not
|
||||
charge any fee for
|
||||
such copies and further provided that each copy
|
||||
contains this
|
||||
Copyright Notice, whether
|
||||
distributed in print or electronically.
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<copyright>
|
||||
<year>2013-2014</year>
|
||||
<holder>The original author(s)</holder>
|
||||
</copyright>
|
||||
</bookinfo>
|
||||
|
||||
<toc/>
|
||||
|
||||
<xi:include href="preface.xml"/>
|
||||
|
||||
<part id="reference">
|
||||
<title>Reference Documentation</title>
|
||||
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.8.0.RELEASE/src/docbkx/repositories.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repositories.xml"/>
|
||||
</xi:include>
|
||||
|
||||
<xi:include href="reference/data-elasticsearch.xml"/>
|
||||
<xi:include href="reference/elasticsearch-misc.xml"/>
|
||||
</part>
|
||||
|
||||
<part id="appendix">
|
||||
<title>Appendix</title>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.8.0.RELEASE/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repository-namespace-reference.xml"/>
|
||||
</xi:include>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.8.0.RELEASE/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repository-query-keywords-reference.xml"/>
|
||||
</xi:include>
|
||||
</part>
|
||||
|
||||
</book>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<preface id="preface">
|
||||
<title>Preface</title>
|
||||
<para>The Spring Data Elasticsearch project applies core Spring
|
||||
concepts to
|
||||
the
|
||||
development of solutions using the Elasticsearch Search
|
||||
Engine.
|
||||
We have povided a "template" as a high-level abstraction for
|
||||
storing,querying,sorting and faceting documents. You will notice
|
||||
similarities
|
||||
to the Spring data solr and
|
||||
mongodb support in the Spring Framework.
|
||||
</para>
|
||||
<section id="project">
|
||||
<title>Project Metadata</title>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Version Control -
|
||||
<ulink
|
||||
url="git://github.com/BioMedCentralLtd/spring-data-elasticsearch.git">
|
||||
git://github.com/BioMedCentralLtd/spring-data-elasticsearch.git
|
||||
</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="requirements">
|
||||
<title>Requirements</title>
|
||||
<para>
|
||||
Requires
|
||||
<ulink url="http://www.elasticsearch.org/download/">Elasticsearch</ulink>
|
||||
0.20.2 and above or optional dependency or not even that if you are
|
||||
using Embedded Node Client
|
||||
</para>
|
||||
</section>
|
||||
</preface>
|
||||
@@ -1,508 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="elasticsearch.repositories">
|
||||
<title>Elasticsearch Repositories</title>
|
||||
<abstract>
|
||||
<para>This chapter includes details of the Elasticsearch repository
|
||||
implementation.
|
||||
</para>
|
||||
</abstract>
|
||||
<section id="elasticsearch.introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<section id="elasticsearch.namespace">
|
||||
<title>Spring Namespace</title>
|
||||
|
||||
<para>
|
||||
The Spring Data Elasticsearch module contains a custom namespace
|
||||
allowing
|
||||
definition of repository beans as well as elements for
|
||||
instantiating
|
||||
a
|
||||
<classname>ElasticsearchServer</classname>
|
||||
.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Using the
|
||||
<code>repositories</code>
|
||||
element looks up Spring Data repositories as described in
|
||||
<xref linkend="repositories.create-instances"/>
|
||||
.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Setting up Elasticsearch repositories using Namespace</title>
|
||||
<programlisting language="xml"><?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></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Using the
|
||||
<code>Transport Client</code>
|
||||
or
|
||||
<code>Node Client</code>
|
||||
element registers an instance of
|
||||
<code>Elasticsearch Server</code>
|
||||
in the context.
|
||||
|
||||
<example>
|
||||
<title>Transport Client using Namespace</title>
|
||||
<programlisting language="xml"><?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> </programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Node Client using Namespace</title>
|
||||
<programlisting language="xml"><?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> </programlisting>
|
||||
</example>
|
||||
</para>
|
||||
</section>
|
||||
<section id="elasticsearch.annotation">
|
||||
<title>Annotation based configuration</title>
|
||||
<para>The Spring Data Elasticsearch repositories support cannot only
|
||||
be
|
||||
activated through an XML namespace but also using an annotation
|
||||
through JavaConfig.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig
|
||||
</title>
|
||||
<programlisting language="java">
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages =
|
||||
"org/springframework/data/elasticsearch/repositories")
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The configuration above sets up an
|
||||
<classname>Embedded Elasticsearch Server</classname>
|
||||
which is used by the
|
||||
<classname>ElasticsearchTemplate</classname>
|
||||
. Spring Data Elasticsearch Repositories are activated using the
|
||||
<interfacename>@EnableElasticsearchRepositories</interfacename>
|
||||
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.
|
||||
</para>
|
||||
</example>
|
||||
</section>
|
||||
<section id="elasticsearch.cdi">
|
||||
<title>Elasticsearch Repositores using CDI</title>
|
||||
<para>The Spring Data Elasticsearch repositories can also be set up
|
||||
using CDI
|
||||
functionality.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig
|
||||
</title>
|
||||
<programlisting language="java">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;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
<section id="elasticsearch.query-methods">
|
||||
<title>Query methods</title>
|
||||
<section id="elasticsearch.query-methods.finders">
|
||||
<title>Query lookup strategies</title>
|
||||
<para>
|
||||
The Elasticsearch module supports all basic query building
|
||||
feature as String,Abstract,Criteria or
|
||||
have
|
||||
it being derived from the
|
||||
method name.
|
||||
</para>
|
||||
|
||||
<simplesect>
|
||||
<title>Declared queries</title>
|
||||
<para>
|
||||
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
|
||||
<interfacename>@Query</interfacename>
|
||||
annotation (see
|
||||
<xref linkend="elasticsearch.query-methods.at-query"/>
|
||||
).
|
||||
</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="elasticsearch.query-methods.criterions">
|
||||
<title>Query creation</title>
|
||||
|
||||
<para>
|
||||
Generally the query creation mechanism for Elasticsearch works as
|
||||
described
|
||||
in
|
||||
<xref linkend="repositories.query-methods"/>
|
||||
. Here's a short example
|
||||
of what a Elasticsearch query method
|
||||
translates into:
|
||||
<example>
|
||||
<title>Query creation from method names</title>
|
||||
<programlisting language="java">public interface BookRepository extends Repository<Book, String>
|
||||
{
|
||||
List<Book> findByNameAndPrice(String name, Integer price);
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The method name above will be translated into the following
|
||||
Elasticsearch json query
|
||||
</para>
|
||||
<programlisting>
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
] } }
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
A list of supported keywords for Elasticsearch is shown below.
|
||||
<table>
|
||||
<title>Supported keywords inside method names</title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="1*"/>
|
||||
<colspec colwidth="2*"/>
|
||||
<colspec colwidth="3*"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Keyword</entry>
|
||||
<entry>Sample</entry>
|
||||
<entry>Elasticsearch Query String</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<code>And</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameAndPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Or</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameOrPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"should" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Is</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByName</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : "?"}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Not</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameNot</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Between</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceBetween</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>LessThanEqual</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceLessThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>GreaterThanEqual</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceGreaterThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Before</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceBefore</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>After</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceAfter</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Like</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameLike</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>StartingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameStartingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>EndingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameEndingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Contains/Containing</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameContaining</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>In</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameIn(Collection<String>names)</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
|
||||
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>NotIn</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameNotIn(Collection<String>names)</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
|
||||
{"name" : "?"}}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Near</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByStoreNear</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>Not Supported Yet !</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>True</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableTrue</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"available" : true}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>False</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableFalse</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"available" : false}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>OrderBy</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableTrueOrderByNameDesc</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
|
||||
{"must" : {"field" : {"available" : true}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
</section>
|
||||
<section id="elasticsearch.query-methods.at-query">
|
||||
<title>Using @Query Annotation</title>
|
||||
<example>
|
||||
<title>
|
||||
Declare query at the method using the
|
||||
<interfacename>@Query</interfacename>
|
||||
annotation.
|
||||
</title>
|
||||
|
||||
<programlisting language="java">public interface BookRepository extends ElasticsearchRepository<Book,
|
||||
String> {
|
||||
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
|
||||
Page<Book> findByName(String name,Pageable pageable);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</chapter>
|
||||
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="elasticsearch.misc">
|
||||
<title>Miscellaneous Elasticsearch Operation Support</title>
|
||||
<abstract>
|
||||
<para>
|
||||
This chapter covers additional support for Elasticsearch operations
|
||||
that cannot be directly accessed via the repository
|
||||
interface.
|
||||
It is
|
||||
recommended to add those operations as custom
|
||||
implementation as
|
||||
described in
|
||||
<xref linkend="repositories.custom-implementations"/>
|
||||
.
|
||||
</para>
|
||||
</abstract>
|
||||
<section id="elasticsearch.misc.filter">
|
||||
<title>Filter Builder</title>
|
||||
<para>
|
||||
Filter Builder improves query speed.
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withFilter(boolFilter().must(termFilter("id", documentId)))
|
||||
.build();
|
||||
Page<SampleEntity> sampleEntities =
|
||||
elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section id="elasticsearch.scan.and.scroll">
|
||||
<title>Using Scan And Scroll For Big Result Set</title>
|
||||
<para>
|
||||
Elasticsearch has scan and scroll feature for getting big result set
|
||||
in chunks.
|
||||
<interfacename>ElasticsearchTemplate</interfacename>
|
||||
has scan and scroll methods that can be used as below.
|
||||
</para>
|
||||
<example>
|
||||
<title>
|
||||
Using Scan and Scroll
|
||||
</title>
|
||||
<programlisting language="java">
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withIndices("test-index")
|
||||
.withTypes("test-type")
|
||||
.withPageable(new PageRequest(0,1))
|
||||
.build();
|
||||
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
|
||||
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
|
||||
boolean hasRecords = true;
|
||||
while (hasRecords){
|
||||
Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
|
||||
{
|
||||
@Override
|
||||
public Page<SampleEntity> mapResults(SearchResponse response) {
|
||||
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
||||
for(SearchHit searchHit : response.getHits()){
|
||||
if(response.getHits().getHits().length <= 0) {
|
||||
return null;
|
||||
}
|
||||
SampleEntity user = new SampleEntity();
|
||||
user.setId(searchHit.getId());
|
||||
user.setMessage((String)searchHit.getSource().get("message"));
|
||||
chunk.add(user);
|
||||
}
|
||||
return new PageImpl<SampleEntity>(chunk);
|
||||
}
|
||||
});
|
||||
if(page != null) {
|
||||
sampleEntities.addAll(page.getContent());
|
||||
hasRecords = page.hasNextPage();
|
||||
}
|
||||
else{
|
||||
hasRecords = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</chapter>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
= Spring Data Elasticsearch
|
||||
BioMed Central Development Team
|
||||
:revnumber: {version}
|
||||
:revdate: {localdate}
|
||||
:toc:
|
||||
:toc-placement!:
|
||||
:spring-data-commons-docs: https://raw.githubusercontent.com/spring-projects/spring-data-commons/master/src/main/asciidoc
|
||||
|
||||
(C) 2013-2014 The original author(s).
|
||||
|
||||
NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
|
||||
|
||||
toc::[]
|
||||
|
||||
include::preface.adoc[]
|
||||
:leveloffset: +1
|
||||
include::{spring-data-commons-docs}/repositories.adoc[]
|
||||
:leveloffset: -1
|
||||
|
||||
[[reference]]
|
||||
= Reference Documentation
|
||||
|
||||
:leveloffset: +1
|
||||
include::reference/data-elasticsearch.adoc[]
|
||||
include::reference/elasticsearch-misc.adoc[]
|
||||
:leveloffset: -1
|
||||
|
||||
[[appendix]]
|
||||
= Appendix
|
||||
:numbered!:
|
||||
:leveloffset: +1
|
||||
include::{spring-data-commons-docs}/repository-namespace-reference.adoc[]
|
||||
include::{spring-data-commons-docs}/repository-populator-namespace-reference.adoc[]
|
||||
include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[]
|
||||
:leveloffset: -1
|
||||
@@ -0,0 +1,20 @@
|
||||
= Preface
|
||||
|
||||
The Spring Data Elasticsearch project applies core Spring concepts to the development of solutions using the Elasticsearch Search Engine. We have povided a "template" as a high-level abstraction for storing,querying,sorting and faceting documents. You will notice similarities to the Spring data solr and mongodb support in the Spring Framework.
|
||||
|
||||
[[project]]
|
||||
[preface]
|
||||
== Project Metadata
|
||||
|
||||
* Version Control - https://github.com/spring-projects/spring-data-elasticsearch
|
||||
* Bugtracker - https://jira.spring.io/browse/DATAES
|
||||
* Release repository - https://repo.spring.io/libs-release
|
||||
* Milestone repository - https://repo.spring.io/libs-milestone
|
||||
* Snapshot repository - https://repo.spring.io/libs-snapshot
|
||||
|
||||
[[requirements]]
|
||||
[preface]
|
||||
== Requirements
|
||||
|
||||
Requires http://www.elasticsearch.org/download/[Elasticsearch] 0.20.2 and above or optional dependency or not even that if you are using Embedded Node Client
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
[[elasticsearch.repositories]]
|
||||
= Elasticsearch Repositories
|
||||
|
||||
This chapter includes details of the Elasticsearch repository implementation.
|
||||
|
||||
[[elasticsearch.introduction]]
|
||||
== Introduction
|
||||
|
||||
[[elasticsearch.namespace]]
|
||||
=== Spring Namespace
|
||||
|
||||
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 <<repositories.create-instances>> .
|
||||
|
||||
.Setting up Elasticsearch repositories using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?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.
|
||||
|
||||
.Transport Client using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
====
|
||||
|
||||
.Node Client using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?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>
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.annotation]]
|
||||
=== Annotation based configuration
|
||||
|
||||
The Spring Data Elasticsearch repositories support cannot only be activated through an XML namespace but also using an annotation through JavaConfig.
|
||||
|
||||
.Spring Data Elasticsearch repositories using JavaConfig
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@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.
|
||||
|
||||
[[elasticsearch.cdi]]
|
||||
=== Elasticsearch Repositores using CDI
|
||||
|
||||
The Spring Data Elasticsearch repositories can also be set up using CDI functionality.
|
||||
|
||||
.Spring Data Elasticsearch repositories using JavaConfig
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
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;
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.query-methods]]
|
||||
== Query methods
|
||||
|
||||
[[elasticsearch.query-methods.finders]]
|
||||
=== Query lookup strategies
|
||||
|
||||
The Elasticsearch module supports all basic query building feature as String,Abstract,Criteria or have it being derived from the method name.
|
||||
|
||||
==== Declared queries
|
||||
|
||||
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 <<elasticsearch.query-methods.at-query>> ).
|
||||
|
||||
[[elasticsearch.query-methods.criterions]]
|
||||
=== Query creation
|
||||
|
||||
Generally the query creation mechanism for Elasticsearch works as described in <<repositories.query-methods>> . Here's a short example of what a Elasticsearch query method translates into:
|
||||
|
||||
.Query creation from method names
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
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
|
||||
|
||||
[source]
|
||||
----
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
]
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
A list of supported keywords for Elasticsearch is shown below.
|
||||
|
||||
[cols="1,2,3", options="header"]
|
||||
.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}}}}`
|
||||
|===
|
||||
|
||||
[[elasticsearch.query-methods.at-query]]
|
||||
=== Using @Query Annotation
|
||||
|
||||
.Declare query at the method using the `@Query` annotation.
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public interface BookRepository extends ElasticsearchRepository<Book, String> {
|
||||
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
|
||||
Page<Book> findByName(String name,Pageable pageable);
|
||||
}
|
||||
----
|
||||
====
|
||||
@@ -0,0 +1,72 @@
|
||||
[[elasticsearch.misc]]
|
||||
= Miscellaneous Elasticsearch Operation Support
|
||||
|
||||
This chapter covers additional support for Elasticsearch operations that cannot be directly accessed via the repository interface. It is recommended to add those operations as custom implementation as described in <<repositories.custom-implementations>> .
|
||||
|
||||
[[elasticsearch.misc.filter]]
|
||||
== Filter Builder
|
||||
|
||||
Filter Builder improves query speed.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withFilter(boolFilter().must(termFilter("id", documentId)))
|
||||
.build();
|
||||
|
||||
Page<SampleEntity> sampleEntities =
|
||||
elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.scan.and.scroll]]
|
||||
== Using Scan And Scroll For Big Result Set
|
||||
|
||||
Elasticsearch has scan and scroll feature for getting big result set in chunks. `ElasticsearchTemplate` has scan and scroll methods that can be used as below.
|
||||
|
||||
.Using Scan and Scroll
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withIndices("test-index")
|
||||
.withTypes("test-type")
|
||||
.withPageable(new PageRequest(0,1))
|
||||
.build();
|
||||
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
|
||||
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
|
||||
boolean hasRecords = true;
|
||||
while (hasRecords){
|
||||
Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
|
||||
{
|
||||
@Override
|
||||
public Page<SampleEntity> mapResults(SearchResponse response) {
|
||||
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
||||
for(SearchHit searchHit : response.getHits()){
|
||||
if(response.getHits().getHits().length <= 0) {
|
||||
return null;
|
||||
}
|
||||
SampleEntity user = new SampleEntity();
|
||||
user.setId(searchHit.getId());
|
||||
user.setMessage((String)searchHit.getSource().get("message"));
|
||||
chunk.add(user);
|
||||
}
|
||||
return new PageImpl<SampleEntity>(chunk);
|
||||
}
|
||||
});
|
||||
if(page != null) {
|
||||
sampleEntities.addAll(page.getContent());
|
||||
hasRecords = page.hasNextPage();
|
||||
}
|
||||
else{
|
||||
hasRecords = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
+53
-8
@@ -29,6 +29,10 @@ import org.elasticsearch.index.query.GeoDistanceFilterBuilder;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -106,20 +110,30 @@ class CriteriaFilterProcessor {
|
||||
Object[] valArray = (Object[]) value;
|
||||
Assert.noNullElements(valArray, "Geo distance filter takes 2 not null elements array as parameter.");
|
||||
Assert.isTrue(valArray.length == 2, "Geo distance filter takes a 2-elements array as parameter.");
|
||||
Assert.isTrue(valArray[0] instanceof GeoPoint || valArray[0] instanceof String, "First element of a geo distance filter must be a GeoLocation or String");
|
||||
Assert.isTrue(valArray[1] instanceof String, "Second element of a geo distance filter must be a String");
|
||||
Assert.isTrue(valArray[0] instanceof GeoPoint || valArray[0] instanceof String || valArray[0] instanceof Point, "First element of a geo distance filter must be a GeoPoint, a Point or a String");
|
||||
Assert.isTrue(valArray[1] instanceof String || valArray[1] instanceof Distance, "Second element of a geo distance filter must be a String or a Distance");
|
||||
|
||||
StringBuilder dist = new StringBuilder();
|
||||
|
||||
if (valArray[1] instanceof Distance) {
|
||||
extractDistanceString((Distance) valArray[1], dist);
|
||||
} else {
|
||||
dist.append((String) valArray[1]);
|
||||
}
|
||||
|
||||
String dist = (String) valArray[1];
|
||||
if (valArray[0] instanceof GeoPoint) {
|
||||
GeoPoint loc = (GeoPoint) valArray[0];
|
||||
((GeoDistanceFilterBuilder) filter).lat(loc.getLat()).lon(loc.getLon()).distance(dist);
|
||||
((GeoDistanceFilterBuilder) filter).lat(loc.getLat()).lon(loc.getLon()).distance(dist.toString());
|
||||
} else if (valArray[0] instanceof Point) {
|
||||
GeoPoint loc = GeoPoint.fromPoint((Point) valArray[0]);
|
||||
((GeoDistanceFilterBuilder) filter).lat(loc.getLat()).lon(loc.getLon()).distance(dist.toString());
|
||||
} else {
|
||||
String loc = (String) valArray[0];
|
||||
if (loc.contains(",")) {
|
||||
String c[] = loc.split(",");
|
||||
((GeoDistanceFilterBuilder) filter).lat(Double.parseDouble(c[0])).lon(Double.parseDouble(c[1])).distance(dist);
|
||||
((GeoDistanceFilterBuilder) filter).lat(Double.parseDouble(c[0])).lon(Double.parseDouble(c[1])).distance(dist.toString());
|
||||
} else {
|
||||
((GeoDistanceFilterBuilder) filter).geohash(loc).distance(dist);
|
||||
((GeoDistanceFilterBuilder) filter).geohash(loc).distance(dist.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,9 +165,40 @@ class CriteriaFilterProcessor {
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* extract the distance string from a {@link org.springframework.data.geo.Distance} object.
|
||||
*
|
||||
* @param distance distance object to extract string from
|
||||
* @param sb StringBuilder to build the distance string
|
||||
*/
|
||||
private void extractDistanceString(Distance distance, StringBuilder sb) {
|
||||
// handle Distance object
|
||||
sb.append((int) distance.getValue());
|
||||
|
||||
Metrics metric = (Metrics) distance.getMetric();
|
||||
|
||||
switch (metric) {
|
||||
case KILOMETERS:
|
||||
sb.append("km");
|
||||
break;
|
||||
case MILES:
|
||||
sb.append("mi");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void oneParameterBBox(GeoBoundingBoxFilterBuilder filter, Object value) {
|
||||
Assert.isTrue(value instanceof GeoBox, "single-element of boundedBy filter must be type of GeoBox");
|
||||
GeoBox geoBBox = (GeoBox) value;
|
||||
Assert.isTrue(value instanceof GeoBox || value instanceof Box, "single-element of boundedBy filter must be type of GeoBox or Box");
|
||||
|
||||
GeoBox geoBBox;
|
||||
if (value instanceof Box) {
|
||||
Box sdbox = (Box) value;
|
||||
geoBBox = GeoBox.fromBox(sdbox);
|
||||
} else {
|
||||
geoBBox = (GeoBox) value;
|
||||
}
|
||||
|
||||
filter.topLeft(geoBBox.getTopLeft().getLat(), geoBBox.getTopLeft().getLon());
|
||||
filter.bottomRight(geoBBox.getBottomRight().getLat(), geoBBox.getBottomRight().getLon());
|
||||
}
|
||||
|
||||
+21
@@ -30,6 +30,7 @@ import org.springframework.data.elasticsearch.core.query.*;
|
||||
*
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
public interface ElasticsearchOperations {
|
||||
|
||||
@@ -246,6 +247,23 @@ public interface ElasticsearchOperations {
|
||||
*/
|
||||
<T> List<String> queryForIds(SearchQuery query);
|
||||
|
||||
/**
|
||||
* return number of elements found by given query
|
||||
*
|
||||
* @param query
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
<T> long count(CriteriaQuery query, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* return number of elements found by given query
|
||||
*
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
<T> long count(CriteriaQuery query);
|
||||
|
||||
/**
|
||||
* return number of elements found by given query
|
||||
*
|
||||
@@ -471,4 +489,7 @@ public interface ElasticsearchOperations {
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryForAlias(String indexName);
|
||||
|
||||
|
||||
<T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor);
|
||||
}
|
||||
|
||||
+95
-19
@@ -50,6 +50,7 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.mlt.MoreLikeThisRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.search.SearchType;
|
||||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||
import org.elasticsearch.action.update.UpdateResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
@@ -64,12 +65,16 @@ import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.facet.FacetBuilder;
|
||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -92,9 +97,10 @@ import org.springframework.util.Assert;
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Artur Konczak
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
|
||||
public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
public class ElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchTemplate.class);
|
||||
private Client client;
|
||||
@@ -188,7 +194,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
Assert.notNull(type, "No type defined for putMapping()");
|
||||
Map mappings = null;
|
||||
try {
|
||||
mappings = client.admin().indices().getMappings(new GetMappingsRequest().indices(indexName).types(type))
|
||||
mappings = client.admin().indices().getMappings(new GetMappingsRequest().indices(indexName).types(type))
|
||||
.actionGet().getMappings().get(indexName).get(type).getSourceAsMap();
|
||||
} catch (Exception e) {
|
||||
throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName + " type : " + type + " " + e.getMessage());
|
||||
@@ -247,6 +253,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
return mapper.mapResults(response, clazz, query.getPageable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor) {
|
||||
SearchResponse response = doSearch(prepareSearch(query), query);
|
||||
return resultsExtractor.extract(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(CriteriaQuery query, Class<T> clazz) {
|
||||
return queryForPage(query, clazz).getContent();
|
||||
@@ -307,10 +319,65 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
return mapper.mapResults(response, clazz, query.getPageable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(CriteriaQuery criteriaQuery, Class<T> clazz) {
|
||||
QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria());
|
||||
FilterBuilder elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria());
|
||||
|
||||
if (elasticsearchFilter == null) {
|
||||
return doCount(prepareCount(criteriaQuery, clazz), elasticsearchQuery);
|
||||
} else {
|
||||
// filter could not be set into CountRequestBuilder, convert request into search request
|
||||
return doCount(prepareSearch(criteriaQuery, clazz), elasticsearchQuery, elasticsearchFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(SearchQuery searchQuery, Class<T> clazz) {
|
||||
String indexName[] = isNotEmpty(searchQuery.getIndices()) ? searchQuery.getIndices().toArray(new String[searchQuery.getIndices().size()]) : retrieveIndexNameFromPersistentEntity(clazz);
|
||||
String types[] = isNotEmpty(searchQuery.getTypes()) ? searchQuery.getTypes().toArray(new String[searchQuery.getTypes().size()]) : retrieveTypeFromPersistentEntity(clazz);
|
||||
QueryBuilder elasticsearchQuery = searchQuery.getQuery();
|
||||
FilterBuilder elasticsearchFilter = searchQuery.getFilter();
|
||||
|
||||
if (elasticsearchFilter == null) {
|
||||
return doCount(prepareCount(searchQuery, clazz), elasticsearchQuery);
|
||||
} else {
|
||||
// filter could not be set into CountRequestBuilder, convert request into search request
|
||||
return doCount(prepareSearch(searchQuery, clazz), elasticsearchQuery, elasticsearchFilter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(CriteriaQuery query) {
|
||||
return count(query, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(SearchQuery query) {
|
||||
return count(query, null);
|
||||
}
|
||||
|
||||
private long doCount(CountRequestBuilder countRequestBuilder, QueryBuilder elasticsearchQuery) {
|
||||
if (elasticsearchQuery != null) {
|
||||
countRequestBuilder.setQuery(elasticsearchQuery);
|
||||
}
|
||||
return countRequestBuilder.execute().actionGet().getCount();
|
||||
}
|
||||
|
||||
private long doCount(SearchRequestBuilder searchRequestBuilder, QueryBuilder elasticsearchQuery, FilterBuilder elasticsearchFilter) {
|
||||
if (elasticsearchQuery != null) {
|
||||
searchRequestBuilder.setQuery(elasticsearchQuery);
|
||||
} else {
|
||||
searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
|
||||
}
|
||||
if (elasticsearchFilter != null) {
|
||||
searchRequestBuilder.setPostFilter(elasticsearchFilter);
|
||||
}
|
||||
searchRequestBuilder.setSearchType(SearchType.COUNT);
|
||||
return searchRequestBuilder.execute().actionGet().getHits().getTotalHits();
|
||||
}
|
||||
|
||||
private <T> CountRequestBuilder prepareCount(Query query, Class<T> clazz) {
|
||||
String indexName[] = isNotEmpty(query.getIndices()) ? query.getIndices().toArray(new String[query.getIndices().size()]) : retrieveIndexNameFromPersistentEntity(clazz);
|
||||
String types[] = isNotEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()]) : retrieveTypeFromPersistentEntity(clazz);
|
||||
|
||||
Assert.notNull(indexName, "No index defined for Query");
|
||||
|
||||
@@ -319,15 +386,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
if (types != null) {
|
||||
countRequestBuilder.setTypes(types);
|
||||
}
|
||||
if (searchQuery.getQuery() != null) {
|
||||
countRequestBuilder.setQuery(searchQuery.getQuery());
|
||||
}
|
||||
return countRequestBuilder.execute().actionGet().getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(SearchQuery query) {
|
||||
return count(query, null);
|
||||
return countRequestBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -384,13 +443,16 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
Assert.notNull(indexName, "No index defined for Query");
|
||||
Assert.notNull(type, "No type define for Query");
|
||||
Assert.notNull(query.getId(), "No Id define for Query");
|
||||
Assert.notNull(query.getIndexRequest(), "No IndexRequest define for Query");
|
||||
Assert.notNull(query.getUpdateRequest(), "No IndexRequest define for Query");
|
||||
UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, type, query.getId());
|
||||
if (query.DoUpsert()) {
|
||||
updateRequestBuilder.setDocAsUpsert(true)
|
||||
.setUpsert(query.getIndexRequest()).setDoc(query.getIndexRequest());
|
||||
.setDoc(query.getUpdateRequest().doc())
|
||||
.setScript(query.getUpdateRequest().script(), query.getUpdateRequest().scriptType())
|
||||
.setScriptParams(query.getUpdateRequest().scriptParams())
|
||||
.setScriptLang(query.getUpdateRequest().scriptLang());
|
||||
} else {
|
||||
updateRequestBuilder.setDoc(query.getIndexRequest());
|
||||
updateRequestBuilder.setDoc(query.getUpdateRequest().doc());
|
||||
}
|
||||
return updateRequestBuilder.execute().actionGet();
|
||||
}
|
||||
@@ -410,7 +472,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
}
|
||||
throw new ElasticsearchException(
|
||||
"Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages ["
|
||||
+ failedDocuments + "]", failedDocuments);
|
||||
+ failedDocuments + "]", failedDocuments
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +557,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
requestBuilder.setPostFilter(searchQuery.getFilter());
|
||||
}
|
||||
|
||||
if(isNotEmpty(searchQuery.getFields())) {
|
||||
if (isNotEmpty(searchQuery.getFields())) {
|
||||
requestBuilder.addFields(toArray(searchQuery.getFields()));
|
||||
}
|
||||
|
||||
@@ -608,6 +671,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(searchQuery.getAggregations())) {
|
||||
for (AbstractAggregationBuilder aggregationBuilder : searchQuery.getAggregations()) {
|
||||
searchRequest.addAggregation(aggregationBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
return searchRequest.setQuery(searchQuery.getQuery()).execute().actionGet();
|
||||
}
|
||||
|
||||
@@ -859,6 +928,13 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
if (elasticsearchConverter instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] toArray(List<String> values) {
|
||||
String[] valuesAsArray = new String[values.size()];
|
||||
return values.toArray(valuesAsArray);
|
||||
@@ -893,7 +969,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations {
|
||||
if (bufferedReader != null)
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
logger.debug(String.format("Unable to close buffered reader.. %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,12 +94,12 @@ class MappingBuilder {
|
||||
boolean isGeoField = isGeoField(field);
|
||||
|
||||
Field singleField = field.getAnnotation(Field.class);
|
||||
if (!isGeoField && isEntity(field) && !isAnnotated(field)) {
|
||||
if (!isGeoField && isEntity(field) && isAnnotated(field)) {
|
||||
if (singleField == null) {
|
||||
continue;
|
||||
}
|
||||
boolean nestedOrObject = isNestedOrObjectField(field);
|
||||
mapEntity(xContentBuilder, getFieldType(field), false, EMPTY, field.getName(), nestedOrObject, field.getAnnotation(Field.class).type());
|
||||
mapEntity(xContentBuilder, getFieldType(field), false, EMPTY, field.getName(), nestedOrObject, singleField.type());
|
||||
if (nestedOrObject) {
|
||||
continue;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ class MappingBuilder {
|
||||
}
|
||||
|
||||
private static boolean isAnnotated(java.lang.reflect.Field field) {
|
||||
return field.getAnnotation(Field.class) == null && field.getAnnotation(MultiField.class) == null && field.getAnnotation(GeoPointField.class) == null;
|
||||
return field.getAnnotation(Field.class) != null || field.getAnnotation(MultiField.class) != null || field.getAnnotation(GeoPointField.class) != null;
|
||||
}
|
||||
|
||||
private static void applyGeoPointFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
|
||||
@@ -146,9 +146,6 @@ class MappingBuilder {
|
||||
/**
|
||||
* Apply mapping for a single @Field annotation
|
||||
*
|
||||
* @param xContentBuilder
|
||||
* @param field
|
||||
* @param fieldAnnotation
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addSingleFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field,
|
||||
@@ -177,9 +174,6 @@ class MappingBuilder {
|
||||
/**
|
||||
* Apply mapping for a single nested @Field annotation
|
||||
*
|
||||
* @param builder
|
||||
* @param field
|
||||
* @param annotation
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addNestedFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
|
||||
@@ -204,9 +198,6 @@ class MappingBuilder {
|
||||
/**
|
||||
* Multi field mappings for string type fields, support for sorts and facets
|
||||
*
|
||||
* @param builder
|
||||
* @param field
|
||||
* @param annotation
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addMultiFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
|
||||
@@ -226,9 +217,6 @@ class MappingBuilder {
|
||||
/**
|
||||
* Facet field for string type, for other types we don't need it(long, int, double, float)
|
||||
*
|
||||
* @param builder
|
||||
* @param field
|
||||
* @param annotation
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addFacetMapping(XContentBuilder builder, java.lang.reflect.Field field, Field annotation) throws IOException {
|
||||
@@ -243,9 +231,6 @@ class MappingBuilder {
|
||||
* Sort field for string type, for other types we don't need it(long, int, double, float)
|
||||
* value of the field should be converted to lowercase and not analise
|
||||
*
|
||||
* @param builder
|
||||
* @param field
|
||||
* @param annotation
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addSortMapping(XContentBuilder builder, java.lang.reflect.Field field, Field annotation) throws IOException {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
|
||||
public interface ResultsExtractor<T> {
|
||||
T extract(SearchResponse response);
|
||||
}
|
||||
+3
@@ -61,5 +61,8 @@ public class MappingElasticsearchConverter implements ElasticsearchConverter, Ap
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
if (mappingContext instanceof ApplicationContextAware) {
|
||||
((ApplicationContextAware) mappingContext).setApplicationContext(applicationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.geo;
|
||||
|
||||
import org.springframework.data.geo.Box;
|
||||
|
||||
/**
|
||||
* Geo bbox used for #{@link org.springframework.data.elasticsearch.core.query.Criteria}.
|
||||
*
|
||||
@@ -37,4 +39,18 @@ public class GeoBox {
|
||||
public GeoPoint getBottomRight() {
|
||||
return bottomRight;
|
||||
}
|
||||
|
||||
/**
|
||||
* return a {@link org.springframework.data.elasticsearch.core.geo.GeoBox}
|
||||
* from a {@link org.springframework.data.geo.Box}.
|
||||
*
|
||||
* @param box {@link org.springframework.data.geo.Box} to use
|
||||
* @return a {@link org.springframework.data.elasticsearch.core.geo.GeoBox}
|
||||
*/
|
||||
public static GeoBox fromBox(Box box) {
|
||||
GeoPoint topLeft = GeoPoint.fromPoint(box.getFirst());
|
||||
GeoPoint bottomRight = GeoPoint.fromPoint(box.getSecond());
|
||||
|
||||
return new GeoBox(topLeft, bottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.geo;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
/**
|
||||
* geo-location used for #{@link org.springframework.data.elasticsearch.core.query.Criteria}.
|
||||
*
|
||||
@@ -41,4 +43,16 @@ public class GeoPoint {
|
||||
public double getLon() {
|
||||
return lon;
|
||||
}
|
||||
|
||||
/**
|
||||
* build a GeoPoint from a {@link org.springframework.data.geo.Point}
|
||||
*
|
||||
* @param point {@link org.springframework.data.geo.Point}
|
||||
* @return a {@link org.springframework.data.elasticsearch.core.geo.GeoPoint}
|
||||
*/
|
||||
public static GeoPoint fromPoint(Point point) {
|
||||
return new GeoPoint(point.getY(), point.getX());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-2
@@ -18,6 +18,9 @@ package org.springframework.data.elasticsearch.core.mapping;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
@@ -30,11 +33,18 @@ import org.springframework.data.util.TypeInformation;
|
||||
*/
|
||||
|
||||
public class SimpleElasticsearchMappingContext extends
|
||||
AbstractMappingContext<SimpleElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> {
|
||||
AbstractMappingContext<SimpleElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> implements ApplicationContextAware {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
protected <T> SimpleElasticsearchPersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new SimpleElasticsearchPersistentEntity<T>(typeInformation);
|
||||
final SimpleElasticsearchPersistentEntity<T> persistentEntity =
|
||||
new SimpleElasticsearchPersistentEntity<T>(typeInformation);
|
||||
if (context != null) {
|
||||
persistentEntity.setApplicationContext(context);
|
||||
}
|
||||
return persistentEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,4 +52,9 @@ public class SimpleElasticsearchMappingContext extends
|
||||
SimpleElasticsearchPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new SimpleElasticsearchPersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -29,6 +29,9 @@ import org.springframework.data.elasticsearch.annotations.Parent;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -43,6 +46,8 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
implements ElasticsearchPersistentEntity<T>, ApplicationContextAware {
|
||||
|
||||
private final StandardEvaluationContext context;
|
||||
private final SpelExpressionParser parser;
|
||||
|
||||
private String indexName;
|
||||
private String indexType;
|
||||
private short shards;
|
||||
@@ -56,6 +61,8 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
public SimpleElasticsearchPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
super(typeInformation);
|
||||
this.context = new StandardEvaluationContext();
|
||||
this.parser = new SpelExpressionParser();
|
||||
|
||||
Class<T> clazz = typeInformation.getType();
|
||||
if (clazz.isAnnotationPresent(Document.class)) {
|
||||
Document document = clazz.getAnnotation(Document.class);
|
||||
@@ -82,7 +89,8 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
|
||||
@Override
|
||||
public String getIndexName() {
|
||||
return indexName;
|
||||
Expression expression = parser.parseExpression(indexName, ParserContext.TEMPLATE_EXPRESSION);
|
||||
return expression.getValue(context, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -360,6 +362,21 @@ public class Criteria {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new CriteriaEntry for {@code location WITHIN distance}
|
||||
*
|
||||
* @param location {@link org.springframework.data.geo.Point} center coordinates
|
||||
* @param distance {@link org.springframework.data.geo.Distance} radius
|
||||
* .
|
||||
* @return Criteria the chaind criteria with the new 'within' criteria included.
|
||||
*/
|
||||
public Criteria within(Point location, Distance distance) {
|
||||
Assert.notNull(location, "Location value for near criteria must not be null");
|
||||
Assert.notNull(location, "Distance value for near criteria must not be null");
|
||||
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{location, distance}));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new CriteriaEntry for {@code geoLocation WITHIN distance}
|
||||
*
|
||||
|
||||
+22
-3
@@ -15,15 +15,16 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* NativeSearchQuery
|
||||
*
|
||||
@@ -37,6 +38,7 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
||||
private FilterBuilder filter;
|
||||
private List<SortBuilder> sorts;
|
||||
private List<FacetRequest> facets;
|
||||
private List<AbstractAggregationBuilder> aggregations;
|
||||
private HighlightBuilder.Field[] highlightFields;
|
||||
|
||||
|
||||
@@ -94,4 +96,21 @@ public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
|
||||
public List<FacetRequest> getFacets() {
|
||||
return facets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractAggregationBuilder> getAggregations() {
|
||||
return aggregations;
|
||||
}
|
||||
|
||||
|
||||
public void addAggregation(AbstractAggregationBuilder aggregationBuilder) {
|
||||
if (aggregations == null) {
|
||||
aggregations = new ArrayList<AbstractAggregationBuilder>();
|
||||
}
|
||||
aggregations.add(aggregationBuilder);
|
||||
}
|
||||
|
||||
public void setAggregations(List<AbstractAggregationBuilder> aggregations) {
|
||||
this.aggregations = aggregations;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -23,6 +23,7 @@ import org.apache.commons.collections.CollectionUtils;
|
||||
import org.elasticsearch.action.search.SearchType;
|
||||
import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -42,6 +43,7 @@ public class NativeSearchQueryBuilder {
|
||||
private FilterBuilder filterBuilder;
|
||||
private List<SortBuilder> sortBuilders = new ArrayList<SortBuilder>();
|
||||
private List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
|
||||
private List<AbstractAggregationBuilder> aggregationBuilders = new ArrayList<AbstractAggregationBuilder>();
|
||||
private HighlightBuilder.Field[] highlightFields;
|
||||
private Pageable pageable;
|
||||
private String[] indices;
|
||||
@@ -67,6 +69,11 @@ public class NativeSearchQueryBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder addAggregation(AbstractAggregationBuilder aggregationBuilder) {
|
||||
this.aggregationBuilders.add(aggregationBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder withFacet(FacetRequest facetRequest) {
|
||||
facetRequests.add(facetRequest);
|
||||
return this;
|
||||
@@ -139,6 +146,10 @@ public class NativeSearchQueryBuilder {
|
||||
nativeSearchQuery.setFacets(facetRequests);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(aggregationBuilders)) {
|
||||
nativeSearchQuery.setAggregations(aggregationBuilders);
|
||||
}
|
||||
|
||||
if (minScore > 0) {
|
||||
nativeSearchQuery.setMinScore(minScore);
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@ public interface Query {
|
||||
|
||||
/**
|
||||
* Type of search
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SearchType getSearchType();
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.List;
|
||||
|
||||
import org.elasticsearch.index.query.FilterBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
@@ -40,5 +41,7 @@ public interface SearchQuery extends Query {
|
||||
|
||||
List<FacetRequest> getFacets();
|
||||
|
||||
List<AbstractAggregationBuilder> getAggregations();
|
||||
|
||||
HighlightBuilder.Field[] getHighlightFields();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.update.UpdateRequest;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
@@ -24,7 +25,7 @@ import org.elasticsearch.action.index.IndexRequest;
|
||||
public class UpdateQuery {
|
||||
|
||||
private String id;
|
||||
private IndexRequest indexRequest;
|
||||
private UpdateRequest updateRequest;
|
||||
private String indexName;
|
||||
private String type;
|
||||
private Class clazz;
|
||||
@@ -38,12 +39,12 @@ public class UpdateQuery {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public IndexRequest getIndexRequest() {
|
||||
return indexRequest;
|
||||
public UpdateRequest getUpdateRequest() {
|
||||
return updateRequest;
|
||||
}
|
||||
|
||||
public void setIndexRequest(IndexRequest indexRequest) {
|
||||
this.indexRequest = indexRequest;
|
||||
public void setUpdateRequest(UpdateRequest updateRequest) {
|
||||
this.updateRequest = updateRequest;
|
||||
}
|
||||
|
||||
public String getIndexName() {
|
||||
|
||||
+14
-1
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.update.UpdateRequest;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
@@ -24,6 +25,7 @@ import org.elasticsearch.action.index.IndexRequest;
|
||||
public class UpdateQueryBuilder {
|
||||
|
||||
private String id;
|
||||
private UpdateRequest updateRequest;
|
||||
private IndexRequest indexRequest;
|
||||
private String indexName;
|
||||
private String type;
|
||||
@@ -35,6 +37,11 @@ public class UpdateQueryBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateQueryBuilder withUpdateRequest(UpdateRequest updateRequest) {
|
||||
this.updateRequest = updateRequest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateQueryBuilder withIndexRequest(IndexRequest indexRequest) {
|
||||
this.indexRequest = indexRequest;
|
||||
return this;
|
||||
@@ -66,7 +73,13 @@ public class UpdateQueryBuilder {
|
||||
updateQuery.setIndexName(indexName);
|
||||
updateQuery.setType(type);
|
||||
updateQuery.setClazz(clazz);
|
||||
updateQuery.setIndexRequest(indexRequest);
|
||||
if (this.indexRequest != null) {
|
||||
if (this.updateRequest == null) {
|
||||
updateRequest = new UpdateRequest();
|
||||
}
|
||||
updateRequest.doc(indexRequest);
|
||||
}
|
||||
updateQuery.setUpdateRequest(updateRequest);
|
||||
updateQuery.setDoUpsert(doUpsert);
|
||||
return updateQuery;
|
||||
}
|
||||
|
||||
+18
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import java.util.Set;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory;
|
||||
import org.springframework.data.repository.cdi.CdiRepositoryBean;
|
||||
import org.springframework.data.repository.config.CustomRepositoryImplementationDetector;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -31,24 +32,36 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ElasticsearchRepositoryBean<T> extends CdiRepositoryBean<T> {
|
||||
|
||||
private final Bean<ElasticsearchOperations> elasticsearchOperationsBean;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ElasticsearchRepositoryBean}.
|
||||
*
|
||||
* @param operations must not be {@literal null}.
|
||||
* @param qualifiers must not be {@literal null}.
|
||||
* @param repositoryType must not be {@literal null}.
|
||||
* @param beanManager must not be {@literal null}.
|
||||
* @param detector detector for the custom {@link org.springframework.data.repository.Repository} implementations
|
||||
* {@link CustomRepositoryImplementationDetector}, can be {@literal null}.
|
||||
*/
|
||||
public ElasticsearchRepositoryBean(Bean<ElasticsearchOperations> operations, Set<Annotation> qualifiers,
|
||||
Class<T> repositoryType, BeanManager beanManager) {
|
||||
super(qualifiers, repositoryType, beanManager);
|
||||
Class<T> repositoryType, BeanManager beanManager, CustomRepositoryImplementationDetector detector) {
|
||||
super(qualifiers, repositoryType, beanManager, detector);
|
||||
|
||||
Assert.notNull(operations, "Cannot create repository with 'null' for ElasticsearchOperations.");
|
||||
this.elasticsearchOperationsBean = operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType) {
|
||||
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType, Object customImplementation) {
|
||||
ElasticsearchOperations elasticsearchOperations = getDependencyInstance(elasticsearchOperationsBean,
|
||||
ElasticsearchOperations.class);
|
||||
return new ElasticsearchRepositoryFactory(elasticsearchOperations).getRepository(repositoryType);
|
||||
return new ElasticsearchRepositoryFactory(elasticsearchOperations).getRepository(repositoryType,
|
||||
customImplementation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-2
@@ -38,6 +38,7 @@ import org.springframework.data.repository.cdi.CdiRepositoryExtensionSupport;
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ElasticsearchRepositoryExtension extends CdiRepositoryExtensionSupport {
|
||||
|
||||
@@ -65,7 +66,8 @@ public class ElasticsearchRepositoryExtension extends CdiRepositoryExtensionSupp
|
||||
}
|
||||
}
|
||||
|
||||
private <T> CdiRepositoryBean<T> createRepositoryBean(Class<T> repositoryType, Set<Annotation> qualifiers, BeanManager beanManager) {
|
||||
private <T> CdiRepositoryBean<T> createRepositoryBean(Class<T> repositoryType, Set<Annotation> qualifiers,
|
||||
BeanManager beanManager) {
|
||||
|
||||
Bean<ElasticsearchOperations> elasticsearchOperationsBean = this.elasticsearchOperationsMap.get(qualifiers
|
||||
.toString());
|
||||
@@ -75,6 +77,7 @@ public class ElasticsearchRepositoryExtension extends CdiRepositoryExtensionSupp
|
||||
ElasticsearchOperations.class.getName(), qualifiers));
|
||||
}
|
||||
|
||||
return new ElasticsearchRepositoryBean<T>(elasticsearchOperationsBean, qualifiers, repositoryType, beanManager);
|
||||
return new ElasticsearchRepositoryBean<T>(elasticsearchOperationsBean, qualifiers, repositoryType, beanManager,
|
||||
getCustomImplementationDetector());
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -15,8 +15,16 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repository.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
|
||||
@@ -72,4 +80,22 @@ public class ElasticsearchRepositoryConfigExtension extends RepositoryConfigurat
|
||||
Element element = config.getElement();
|
||||
builder.addPropertyReference("elasticsearchOperations", element.getAttribute("elasticsearch-template-ref"));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingAnnotations()
|
||||
*/
|
||||
@Override
|
||||
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
|
||||
return Collections.<Class<? extends Annotation>>singleton(Document.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getIdentifyingTypes()
|
||||
*/
|
||||
@Override
|
||||
protected Collection<Class<?>> getIdentifyingTypes() {
|
||||
return Arrays.<Class<?>>asList(ElasticsearchRepository.class, ElasticsearchCrudRepository.class);
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -28,6 +28,7 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
*
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
|
||||
|
||||
@@ -52,6 +53,8 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
|
||||
query.setPageable(accessor.getPageable());
|
||||
}
|
||||
return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
|
||||
} else if (tree.isCountProjection()) {
|
||||
return elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
||||
}
|
||||
return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType());
|
||||
}
|
||||
|
||||
+1
-7
@@ -19,8 +19,6 @@ import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.elasticsearch.annotations.Query;
|
||||
import org.springframework.data.elasticsearch.repository.support.ElasticsearchEntityInformation;
|
||||
import org.springframework.data.elasticsearch.repository.support.ElasticsearchEntityInformationCreator;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -33,14 +31,10 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class ElasticsearchQueryMethod extends QueryMethod {
|
||||
|
||||
private final ElasticsearchEntityInformation<?, ?> entityInformation;
|
||||
private Method method;
|
||||
|
||||
public ElasticsearchQueryMethod(Method method, RepositoryMetadata metadata,
|
||||
ElasticsearchEntityInformationCreator elasticsearchEntityInformationCreator) {
|
||||
public ElasticsearchQueryMethod(Method method, RepositoryMetadata metadata) {
|
||||
super(method, metadata);
|
||||
this.entityInformation = elasticsearchEntityInformationCreator.getEntityInformation(metadata
|
||||
.getReturnedDomainClass(method));
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
|
||||
+43
@@ -20,9 +20,14 @@ import java.util.Iterator;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.context.PersistentPropertyPath;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
@@ -35,6 +40,7 @@ import org.springframework.data.repository.query.parser.PartTree;
|
||||
*
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Franck Marchand
|
||||
*/
|
||||
public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuery, CriteriaQuery> {
|
||||
|
||||
@@ -120,6 +126,43 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
|
||||
return criteria.in(asArray(parameters.next()));
|
||||
case NOT_IN:
|
||||
return criteria.in(asArray(parameters.next())).not();
|
||||
case WITHIN: {
|
||||
Object firstParameter = parameters.next();
|
||||
Object secondParameter = parameters.next();
|
||||
|
||||
if (firstParameter instanceof GeoPoint && secondParameter instanceof String)
|
||||
return criteria.within((GeoPoint) firstParameter, (String) secondParameter);
|
||||
|
||||
if (firstParameter instanceof Point && secondParameter instanceof Distance)
|
||||
return criteria.within((Point) firstParameter, (Distance) secondParameter);
|
||||
|
||||
if (firstParameter instanceof String && secondParameter instanceof String)
|
||||
return criteria.within((String) firstParameter, (String) secondParameter);
|
||||
}
|
||||
case NEAR: {
|
||||
Object firstParameter = parameters.next();
|
||||
|
||||
if (firstParameter instanceof GeoBox) {
|
||||
return criteria.boundedBy((GeoBox) firstParameter);
|
||||
}
|
||||
|
||||
if (firstParameter instanceof Box) {
|
||||
return criteria.boundedBy(GeoBox.fromBox((Box) firstParameter));
|
||||
}
|
||||
|
||||
Object secondParameter = parameters.next();
|
||||
|
||||
// "near" query can be the same query as the "within" query
|
||||
if (firstParameter instanceof GeoPoint && secondParameter instanceof String)
|
||||
return criteria.within((GeoPoint) firstParameter, (String) secondParameter);
|
||||
|
||||
if (firstParameter instanceof Point && secondParameter instanceof Distance)
|
||||
return criteria.within((Point) firstParameter, (Distance) secondParameter);
|
||||
|
||||
if (firstParameter instanceof String && secondParameter instanceof String)
|
||||
return criteria.within((String) firstParameter, (String) secondParameter);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
|
||||
}
|
||||
|
||||
+1
@@ -47,6 +47,7 @@ public class ElasticsearchEntityInformationCreatorImpl implements ElasticsearchE
|
||||
.getPersistentEntity(domainClass);
|
||||
|
||||
Assert.notNull(persistentEntity, String.format("Unable to obtain mapping metadata for %s!", domainClass));
|
||||
Assert.notNull(persistentEntity.getIdProperty(), String.format("No id property found for %s!", domainClass));
|
||||
|
||||
return new MappingElasticsearchEntityInformation<T, ID>(persistentEntity);
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport {
|
||||
@Override
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
|
||||
|
||||
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method, metadata, entityInformationCreator);
|
||||
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method, metadata);
|
||||
String namedQueryName = queryMethod.getNamedQueryName();
|
||||
|
||||
if (namedQueries.hasQuery(namedQueryName)) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,114 @@
|
||||
Spring Data Elasticsearch Changelog
|
||||
===================================
|
||||
|
||||
Changes in version 1.1.3.RELEASE (2015-07-01)
|
||||
---------------------------------------------
|
||||
* DATAES-174 - Release 1.1.3 (Evans).
|
||||
|
||||
|
||||
Changes in version 1.2.1.RELEASE (2015-06-30)
|
||||
---------------------------------------------
|
||||
* DATAES-175 - Release 1.2.1 (Fowler).
|
||||
* DATAES-164 - CriteriaQuery equals method has to use AND operator instead of OR.
|
||||
* DATAES-155 - findAll(Iterable<ID> ids) doesn't set persistent entity id.
|
||||
|
||||
|
||||
Changes in version 1.3.0.M1 (2015-06-02)
|
||||
----------------------------------------
|
||||
* DATAES-168 - Release 1.3 M1 (Gosling).
|
||||
* DATAES-164 - CriteriaQuery equals method has to use AND operator instead of OR.
|
||||
* DATAES-162 - Adapt API changes in Spring Data Commons to simplify custom repository base class registration.
|
||||
* DATAES-159 - Bulk update with ElasticsearchTemplate.
|
||||
* DATAES-158 - UpdateRequest.script not working.
|
||||
* DATAES-157 - support deleteBy operation.
|
||||
* DATAES-155 - findAll(Iterable<ID> ids) doesn't set persistent entity id.
|
||||
|
||||
|
||||
Changes in version 1.2.0.RELEASE (2015-03-23)
|
||||
---------------------------------------------
|
||||
* DATAES-154 - Release 1.2 GA.
|
||||
|
||||
|
||||
Changes in version 1.2.0.RC1 (2015-03-05)
|
||||
-----------------------------------------
|
||||
* DATAES-152 - Release 1.2 RC1.
|
||||
* DATAES-151 - findAll(Iterable<ID> ids) uses id representation in source instead of ES id.
|
||||
* DATAES-140 - Document fields should not be indexed for search.
|
||||
* DATAES-135 - Add necessary implementation for improved multi-store behavior.
|
||||
* DATAES-132 - support include_in_parent for nested fieldtype.
|
||||
* DATAES-130 - Allow Spring EL usage in type attribute of @Document.
|
||||
* DATAES-129 - Custom Repository Method for simple geo request does not work.
|
||||
* DATAES-115 - FindBy projections for list returns only 10 results.
|
||||
* DATAES-100 - Allow configurable searchTimeout.
|
||||
* DATAES-94 - Bump to support ES 1.2.0.
|
||||
* DATAES-91 - Support for 'suggest' operations.
|
||||
|
||||
|
||||
Changes in version 1.1.2.RELEASE (2015-01-28)
|
||||
---------------------------------------------
|
||||
* DATAES-146 - Release 1.1.2.
|
||||
|
||||
|
||||
Changes in version 1.0.5.RELEASE (2015-01-27)
|
||||
---------------------------------------------
|
||||
* DATAES-145 - Release 1.0.5.
|
||||
|
||||
|
||||
Changes in version 1.2.0.M1 (2014-12-01)
|
||||
----------------------------------------
|
||||
* DATAES-134 - Release 1.2 M1.
|
||||
* DATAES-94 - Support for Elasticsearch 1.2.0.
|
||||
* DATAES-76 - Add support for mapping generation of inherited fields.
|
||||
|
||||
|
||||
Changes in version 1.1.1.RELEASE (2014-10-30)
|
||||
---------------------------------------------
|
||||
* DATAES-133 - Release 1.1.1.
|
||||
|
||||
|
||||
Changes in version 1.1.0.RELEASE (2014-09-05)
|
||||
---------------------------------------------
|
||||
* DATAES-128 - Release 1.1 GA.
|
||||
* DATAES-125 - the name of the isAnnotated method doesn't correspond to method body.
|
||||
* DATAES-123 - Custom repository implementations are not picked up when using CDI.
|
||||
* DATAES-120 - Polish reference documentation.
|
||||
* DATAES-106 - Add support for countBy projections.
|
||||
|
||||
|
||||
Changes in version 1.0.4.RELEASE (2014-08-27)
|
||||
---------------------------------------------
|
||||
* DATAES-122 - Release 1.0.4.
|
||||
|
||||
|
||||
Changes in version 1.1.0.RC1 (2014-08-13)
|
||||
-----------------------------------------
|
||||
* DATAES-119 - Release 1.1 RC1.
|
||||
* DATAES-117 - Displaying proper error message for entities that don't have an Id.
|
||||
* DATAES-116 - Fix url typo in readme.md.
|
||||
* DATAES-114 - Move to Asciidoctor for reference documentation.
|
||||
* DATAES-113 - Add support for custom implementations in CDI repositories.
|
||||
* DATAES-97 - UpdateQuery and UpdateBuilder should use UpdateRequest instead of the IndexRequest.
|
||||
* DATAES-93 - Allow Spring EL usage in index name attribute of @Document.
|
||||
* DATAES-89 - Support geolocation queries.
|
||||
|
||||
|
||||
Changes in version 1.0.2.RELEASE (2014-07-28)
|
||||
---------------------------------------------
|
||||
* DATAES-107 - Release 1.0.2.
|
||||
|
||||
|
||||
Changes in version 1.1.0.M1 (2014-07-10)
|
||||
----------------------------------------
|
||||
* DATAES-102 - Release 1.1 M1.
|
||||
* DATAES-96 - Add support for aggregation in ElasticsearchTemplate.
|
||||
* DATAES-94 - Bump to support ES 1.2.0.
|
||||
|
||||
|
||||
Changes in version 1.0.1.RELEASE (2014-06-30)
|
||||
---------------------------------------------
|
||||
* DATAES-99 - Release 1.0.1.
|
||||
|
||||
|
||||
Changes in version 1.0.0.RELEASE (2014-05-20)
|
||||
---------------------------------------------
|
||||
* DATAES-90 - Release 1.0 GA.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Spring Data Elasticsearch 1.0 GA
|
||||
Copyright (c) [2013-2014] Pivotal Software, Inc.
|
||||
Spring Data Elasticsearch 1.1.3
|
||||
Copyright (c) [2013-2015] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
You may not use this product except in compliance with the License.
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch;
|
||||
|
||||
import static org.hamcrest.core.Is.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
||||
import org.springframework.data.elasticsearch.entities.SpELEntity;
|
||||
import org.springframework.data.elasticsearch.repositories.spel.SpELRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* SpELEntityTest
|
||||
*
|
||||
* @author Artur Konczak
|
||||
*
|
||||
*/
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:/spel-repository-test.xml")
|
||||
public class SpELEntityTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
private SpELRepository repository;
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchTemplate template;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
repository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDo() {
|
||||
//Given
|
||||
repository.save(new SpELEntity());
|
||||
repository.save(new SpELEntity());
|
||||
//When
|
||||
|
||||
//Then
|
||||
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
|
||||
nativeSearchQuery.addIndices("abz-entity");
|
||||
long count = template.count(nativeSearchQuery);
|
||||
assertThat(count, is(2L));
|
||||
}
|
||||
}
|
||||
+24
-1
@@ -21,12 +21,16 @@ import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.repositories.sample.SampleElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -37,7 +41,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class EnableElasticsearchRepositoriesTests {
|
||||
public class EnableElasticsearchRepositoriesTests implements ApplicationContextAware {
|
||||
|
||||
ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "org.springframework.data.elasticsearch.repositories.sample")
|
||||
@@ -56,4 +67,16 @@ public class EnableElasticsearchRepositoriesTests {
|
||||
public void bootstrapsRepository() {
|
||||
assertThat(repository, is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldScanSelectedPackage() {
|
||||
//given
|
||||
|
||||
//when
|
||||
String[] beanNamesForType = context.getBeanNamesForType(ElasticsearchRepository.class);
|
||||
|
||||
//then
|
||||
assertThat(beanNamesForType.length, is(1));
|
||||
assertThat(beanNamesForType[0], is("sampleElasticsearchRepository"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,5 +199,4 @@ public class AliasTests {
|
||||
elasticsearchTemplate.putMapping(SampleEntity.class);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+171
-16
@@ -58,6 +58,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Mohsin Husen
|
||||
* @author Franck Marchand
|
||||
* @author Abdul Mohammed
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
||||
@@ -80,6 +81,26 @@ public class ElasticsearchTemplateTests {
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnCountForGivenCriteriaQuery() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = getIndexQuery(sampleEntity);
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnCountForGivenSearchQuery() {
|
||||
// given
|
||||
@@ -621,7 +642,7 @@ public class ElasticsearchTemplateTests {
|
||||
@Override
|
||||
public <T> FacetedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
||||
List<SampleEntity> result = new ArrayList<SampleEntity>();
|
||||
for(SearchHit searchHit : response.getHits()){
|
||||
for (SearchHit searchHit : response.getHits()) {
|
||||
String message = searchHit.getFields().get("message").getValue();
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(searchHit.getId());
|
||||
@@ -629,7 +650,7 @@ public class ElasticsearchTemplateTests {
|
||||
result.add(sampleEntity);
|
||||
}
|
||||
|
||||
if(result.size() > 0) {
|
||||
if (result.size() > 0) {
|
||||
return new FacetedPageImpl<T>((List<T>) result);
|
||||
}
|
||||
return null;
|
||||
@@ -1187,6 +1208,27 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(sampleEntities.getTotalElements(), greaterThanOrEqualTo(1L));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQuery() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = getIndexQuery(sampleEntity);
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
criteriaQuery.addIndices("test-index");
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-67
|
||||
*/
|
||||
@@ -1210,6 +1252,28 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCriteriaQuery() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = getIndexQuery(sampleEntity);
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
criteriaQuery.addIndices("test-index");
|
||||
criteriaQuery.addTypes("test-type");
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-67
|
||||
*/
|
||||
@@ -1234,6 +1298,43 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() {
|
||||
// given
|
||||
cleanUpIndices();
|
||||
String documentId1 = randomNumeric(5);
|
||||
SampleEntity sampleEntity1 = new SampleEntityBuilder(documentId1).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId())
|
||||
.withIndexName("test-index-1")
|
||||
.withObject(sampleEntity1)
|
||||
.build();
|
||||
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntityBuilder(documentId2).message("some test message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId())
|
||||
.withIndexName("test-index-2")
|
||||
.withObject(sampleEntity2)
|
||||
.build();
|
||||
|
||||
elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2));
|
||||
elasticsearchTemplate.refresh("test-index-1", true);
|
||||
elasticsearchTemplate.refresh("test-index-2", true);
|
||||
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
criteriaQuery.addIndices("test-index-1", "test-index-2");
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery);
|
||||
// then
|
||||
assertThat(count, is(equalTo(2L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-67
|
||||
*/
|
||||
@@ -1310,6 +1411,43 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(elasticsearchTemplate.indexExists("test-index"), is(false));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificIndex() {
|
||||
// given
|
||||
cleanUpIndices();
|
||||
String documentId1 = randomNumeric(5);
|
||||
SampleEntity sampleEntity1 = new SampleEntityBuilder(documentId1).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId())
|
||||
.withIndexName("test-index-1")
|
||||
.withObject(sampleEntity1)
|
||||
.build();
|
||||
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntityBuilder(documentId2).message("some test message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId())
|
||||
.withIndexName("test-index-2")
|
||||
.withObject(sampleEntity2)
|
||||
.build();
|
||||
|
||||
elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2));
|
||||
elasticsearchTemplate.refresh("test-index-1", true);
|
||||
elasticsearchTemplate.refresh("test-index-2", true);
|
||||
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
criteriaQuery.addIndices("test-index-1");
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-67
|
||||
*/
|
||||
@@ -1349,11 +1487,28 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCountQuery() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = getIndexQuery(sampleEntity);
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
|
||||
// when
|
||||
long count = elasticsearchTemplate.count(criteriaQuery);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-67
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowAnExceptionWhenNoIndexSpecifiedForCountQuery() {
|
||||
public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCountQuery() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntityBuilder(documentId).message("some message")
|
||||
@@ -1378,19 +1533,19 @@ public class ElasticsearchTemplateTests {
|
||||
public void shouldCreateIndexWithGivenSettings() {
|
||||
// given
|
||||
String settings = "{\n" +
|
||||
" \"index\": {\n" +
|
||||
" \"number_of_shards\": \"1\",\n" +
|
||||
" \"number_of_replicas\": \"0\",\n" +
|
||||
" \"analysis\": {\n" +
|
||||
" \"analyzer\": {\n" +
|
||||
" \"emailAnalyzer\": {\n" +
|
||||
" \"type\": \"custom\",\n" +
|
||||
" \"tokenizer\": \"uax_url_email\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
" \"index\": {\n" +
|
||||
" \"number_of_shards\": \"1\",\n" +
|
||||
" \"number_of_replicas\": \"0\",\n" +
|
||||
" \"analysis\": {\n" +
|
||||
" \"analyzer\": {\n" +
|
||||
" \"emailAnalyzer\": {\n" +
|
||||
" \"type\": \"custom\",\n" +
|
||||
" \"tokenizer\": \"uax_url_email\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
elasticsearchTemplate.deleteIndex("test-index");
|
||||
// when
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.aggregation;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.search.aggregations.Aggregations;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ResultsExtractor;
|
||||
import org.springframework.data.elasticsearch.core.facet.ArticleEntity;
|
||||
import org.springframework.data.elasticsearch.core.facet.ArticleEntityBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import static org.elasticsearch.action.search.SearchType.COUNT;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Jonathan Yan
|
||||
* @author Artur Konczak
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
||||
public class ElasticsearchTemplateAggregationTests {
|
||||
|
||||
public static final String RIZWAN_IDREES = "Rizwan Idrees";
|
||||
public static final String MOHSIN_HUSEN = "Mohsin Husen";
|
||||
public static final String JONATHAN_YAN = "Jonathan Yan";
|
||||
public static final String ARTUR_KONCZAK = "Artur Konczak";
|
||||
public static final int YEAR_2002 = 2002;
|
||||
public static final int YEAR_2001 = 2001;
|
||||
public static final int YEAR_2000 = 2000;
|
||||
@Autowired
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
elasticsearchTemplate.deleteIndex(ArticleEntity.class);
|
||||
elasticsearchTemplate.createIndex(ArticleEntity.class);
|
||||
elasticsearchTemplate.putMapping(ArticleEntity.class);
|
||||
elasticsearchTemplate.refresh(ArticleEntity.class, true);
|
||||
|
||||
IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10).buildIndex();
|
||||
IndexQuery article2 = new ArticleEntityBuilder("2").title("article three").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addPublishedYear(YEAR_2000).score(20).buildIndex();
|
||||
IndexQuery article3 = new ArticleEntityBuilder("3").title("article two").subject("computing").addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(30).buildIndex();
|
||||
IndexQuery article4 = new ArticleEntityBuilder("4").title("article one").subject("accounting").addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(40).buildIndex();
|
||||
|
||||
elasticsearchTemplate.index(article1);
|
||||
elasticsearchTemplate.index(article2);
|
||||
elasticsearchTemplate.index(article3);
|
||||
elasticsearchTemplate.index(article4);
|
||||
elasticsearchTemplate.refresh(ArticleEntity.class, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnAggregatedResponseForGivenSearchQuery() {
|
||||
// given
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withSearchType(COUNT)
|
||||
.withIndices("articles").withTypes("article")
|
||||
.addAggregation(terms("subjects").field("subject"))
|
||||
.build();
|
||||
// when
|
||||
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
|
||||
@Override
|
||||
public Aggregations extract(SearchResponse response) {
|
||||
return response.getAggregations();
|
||||
}
|
||||
});
|
||||
// then
|
||||
assertThat(aggregations, is(notNullValue()));
|
||||
assertThat(aggregations.asMap().get("subjects"), is(notNullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+114
-106
@@ -1,106 +1,114 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.facet;
|
||||
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldIndex.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.Integer;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.String;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
import org.springframework.data.elasticsearch.annotations.NestedField;
|
||||
|
||||
/**
|
||||
* Simple type to test facets
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
*/
|
||||
@Document(indexName = "articles", type = "article", shards = 1, replicas = 0, refreshInterval = "-1", indexStoreType = "memory")
|
||||
public class ArticleEntity {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String title;
|
||||
|
||||
@MultiField(
|
||||
mainField = @Field(type = String, index = analyzed),
|
||||
otherFields = {
|
||||
@NestedField(dotSuffix = "untouched", type = String, store = true, index = not_analyzed),
|
||||
@NestedField(dotSuffix = "sort", type = String, store = true, indexAnalyzer = "keyword")
|
||||
}
|
||||
)
|
||||
private List<String> authors = new ArrayList<String>();
|
||||
|
||||
@Field(type = Integer, store = true)
|
||||
private List<Integer> publishedYears = new ArrayList<Integer>();
|
||||
|
||||
private int score;
|
||||
|
||||
private ArticleEntity() {
|
||||
|
||||
}
|
||||
|
||||
public ArticleEntity(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<String> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public List<Integer> getPublishedYears() {
|
||||
return publishedYears;
|
||||
}
|
||||
|
||||
public void setPublishedYears(List<Integer> publishedYears) {
|
||||
this.publishedYears = publishedYears;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.facet;
|
||||
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldIndex.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.Integer;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.String;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
import org.springframework.data.elasticsearch.annotations.NestedField;
|
||||
|
||||
/**
|
||||
* Simple type to test facets
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
*/
|
||||
@Document(indexName = "articles", type = "article", shards = 1, replicas = 0, refreshInterval = "-1", indexStoreType = "memory")
|
||||
public class ArticleEntity {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
private String title;
|
||||
private String subject;
|
||||
|
||||
@MultiField(
|
||||
mainField = @Field(type = String, index = analyzed),
|
||||
otherFields = {
|
||||
@NestedField(dotSuffix = "untouched", type = String, store = true, index = not_analyzed),
|
||||
@NestedField(dotSuffix = "sort", type = String, store = true, indexAnalyzer = "keyword")
|
||||
}
|
||||
)
|
||||
private List<String> authors = new ArrayList<String>();
|
||||
|
||||
@Field(type = Integer, store = true)
|
||||
private List<Integer> publishedYears = new ArrayList<Integer>();
|
||||
|
||||
private int score;
|
||||
|
||||
private ArticleEntity() {
|
||||
|
||||
}
|
||||
|
||||
public ArticleEntity(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<String> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public List<Integer> getPublishedYears() {
|
||||
return publishedYears;
|
||||
}
|
||||
|
||||
public void setPublishedYears(List<Integer> publishedYears) {
|
||||
this.publishedYears = publishedYears;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
}
|
||||
|
||||
+69
-64
@@ -1,64 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.facet;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
|
||||
/**
|
||||
* Simple type to test facets
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
*/
|
||||
public class ArticleEntityBuilder {
|
||||
|
||||
private ArticleEntity result;
|
||||
|
||||
public ArticleEntityBuilder(String id) {
|
||||
result = new ArticleEntity(id);
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder title(String title) {
|
||||
result.setTitle(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder addAuthor(String author) {
|
||||
result.getAuthors().add(author);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder addPublishedYear(Integer year) {
|
||||
result.getPublishedYears().add(year);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder score(int score) {
|
||||
result.setScore(score);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntity build() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public IndexQuery buildIndex() {
|
||||
IndexQuery indexQuery = new IndexQuery();
|
||||
indexQuery.setId(result.getId());
|
||||
indexQuery.setObject(result);
|
||||
return indexQuery;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.facet;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
|
||||
/**
|
||||
* Simple type to test facets
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
*/
|
||||
public class ArticleEntityBuilder {
|
||||
|
||||
private ArticleEntity result;
|
||||
|
||||
public ArticleEntityBuilder(String id) {
|
||||
result = new ArticleEntity(id);
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder title(String title) {
|
||||
result.setTitle(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder subject(String subject) {
|
||||
result.setSubject(subject);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder addAuthor(String author) {
|
||||
result.getAuthors().add(author);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder addPublishedYear(Integer year) {
|
||||
result.getPublishedYears().add(year);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntityBuilder score(int score) {
|
||||
result.setScore(score);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ArticleEntity build() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public IndexQuery buildIndex() {
|
||||
IndexQuery indexQuery = new IndexQuery();
|
||||
indexQuery.setId(result.getId());
|
||||
indexQuery.setObject(result);
|
||||
return indexQuery;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -16,7 +16,9 @@
|
||||
package org.springframework.data.elasticsearch.entities;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.*;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
|
||||
/**
|
||||
* Sample DynamicSettingAndMappingEntity for test out dynamic setting using @Setting Annotation
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
@@ -35,6 +36,9 @@ public class SampleEntity {
|
||||
private int rate;
|
||||
private boolean available;
|
||||
private String highlightedMessage;
|
||||
|
||||
private GeoPoint location;
|
||||
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
@@ -86,6 +90,14 @@ public class SampleEntity {
|
||||
this.highlightedMessage = highlightedMessage;
|
||||
}
|
||||
|
||||
public GeoPoint getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(GeoPoint location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.entities;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
|
||||
/**
|
||||
* SpELEntity
|
||||
*
|
||||
* @author Artur Konczak
|
||||
*
|
||||
*/
|
||||
@Document(indexName = "#{'abz'+'-'+'entity'}", type = "spel", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
|
||||
public class SpELEntity {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
+640
@@ -30,14 +30,21 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.entities.SampleEntity;
|
||||
import org.springframework.data.elasticsearch.repositories.custom.SampleCustomMethodRepository;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Franck Marchand
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:custom-method-repository-test.xml")
|
||||
@@ -53,6 +60,7 @@ public class CustomMethodRepositoryTests {
|
||||
public void before() {
|
||||
elasticsearchTemplate.deleteIndex(SampleEntity.class);
|
||||
elasticsearchTemplate.createIndex(SampleEntity.class);
|
||||
elasticsearchTemplate.putMapping(SampleEntity.class);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class, true);
|
||||
}
|
||||
|
||||
@@ -486,4 +494,636 @@ public class CustomMethodRepositoryTests {
|
||||
assertThat(sampleEntities.isEmpty(), is(false));
|
||||
assertThat(sampleEntities.size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecuteCustomMethodWithWithinGeoPoint() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// when
|
||||
Page<SampleEntity> page = repository.findByLocationWithin(new GeoPoint(45.7806d, 3.0875d), "2km", new PageRequest(0, 10));
|
||||
// then
|
||||
assertThat(page, is(notNullValue()));
|
||||
assertThat(page.getTotalElements(), is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecuteCustomMethodWithWithinPoint() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// when
|
||||
Page<SampleEntity> page = repository.findByLocationWithin(new Point(3.0875d, 45.7806d), new Distance(2, Metrics.KILOMETERS), new PageRequest(0, 10));
|
||||
// then
|
||||
assertThat(page, is(notNullValue()));
|
||||
assertThat(page.getTotalElements(), is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecuteCustomMethodWithNearBox() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test2");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("foo");
|
||||
sampleEntity2.setLocation(new GeoPoint(30.7806d, 0.0875d));
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
Page<SampleEntity> pageAll = repository.findAll(new PageRequest(0, 10));
|
||||
// then
|
||||
assertThat(pageAll, is(notNullValue()));
|
||||
assertThat(pageAll.getTotalElements(), is(equalTo(2L)));
|
||||
|
||||
// when
|
||||
Page<SampleEntity> page = repository.findByLocationNear(new Box(new Point(3d, 46d), new Point(4d, 45d)), new PageRequest(0, 10));
|
||||
// then
|
||||
assertThat(page, is(notNullValue()));
|
||||
assertThat(page.getTotalElements(), is(equalTo(1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExecuteCustomMethodWithNearPointAndDistance() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// when
|
||||
Page<SampleEntity> page = repository.findByLocationNear(new Point(3.0875d, 45.7806d), new Distance(2, Metrics.KILOMETERS), new PageRequest(0, 10));
|
||||
// then
|
||||
assertThat(page, is(notNullValue()));
|
||||
assertThat(page.getTotalElements(), is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethod() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test2");
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByType("test");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForNot() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("some");
|
||||
sampleEntity.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByTypeNot("test");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithBooleanParameter() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setAvailable(true);
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// given
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("bar");
|
||||
sampleEntity2.setAvailable(false);
|
||||
repository.save(sampleEntity2);
|
||||
// when
|
||||
long count = repository.countByAvailable(false);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithLessThan() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("some message");
|
||||
repository.save(sampleEntity);
|
||||
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(20);
|
||||
sampleEntity2.setMessage("some message");
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByRateLessThan(10);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithBefore() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(20);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByRateBefore(10);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithAfter() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(0);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByRateAfter(10);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithLike() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByMessageLike("fo");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForStartingWith() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByMessageStartingWith("fo");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForEndingWith() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByMessageEndingWith("o");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForContains() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("some message");
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByMessageContaining("fo");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForIn() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("foo");
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// given
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("bar");
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
List<String> ids = Arrays.asList(documentId, documentId2);
|
||||
|
||||
// when
|
||||
long count = repository.countByIdIn(ids);
|
||||
// then
|
||||
assertThat(count, is(equalTo(2L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForNotIn() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("foo");
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// given
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("bar");
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
List<String> ids = Arrays.asList(documentId);
|
||||
|
||||
// when
|
||||
long count = repository.countByIdNotIn(ids);
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForTrue() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setAvailable(true);
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// given
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("bar");
|
||||
sampleEntity2.setAvailable(false);
|
||||
repository.save(sampleEntity2);
|
||||
// when
|
||||
long count = repository.countByAvailableTrue();
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodForFalse() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setAvailable(true);
|
||||
repository.save(sampleEntity);
|
||||
|
||||
// given
|
||||
String documentId2 = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId2);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setMessage("bar");
|
||||
sampleEntity2.setAvailable(false);
|
||||
repository.save(sampleEntity2);
|
||||
// when
|
||||
long count = repository.countByAvailableFalse();
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithWithinGeoPoint() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("foo");
|
||||
sampleEntity2.setLocation(new GeoPoint(30.7806d, 0.0875d));
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByLocationWithin(new GeoPoint(45.7806d, 3.0875d), "2km");
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithWithinPoint() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("foo");
|
||||
sampleEntity2.setLocation(new GeoPoint(30.7806d, 0.0875d));
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByLocationWithin(new Point(3.0875d, 45.7806d), new Distance(2, Metrics.KILOMETERS));
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithNearBox() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test2");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("foo");
|
||||
sampleEntity2.setLocation(new GeoPoint(30.7806d, 0.0875d));
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByLocationNear(new Box(new Point(3d, 46d), new Point(4d, 45d)));
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
/*
|
||||
DATAES-106
|
||||
*/
|
||||
@Test
|
||||
public void shouldCountCustomMethodWithNearPointAndDistance() {
|
||||
// given
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = new SampleEntity();
|
||||
sampleEntity.setId(documentId);
|
||||
sampleEntity.setType("test");
|
||||
sampleEntity.setRate(10);
|
||||
sampleEntity.setMessage("foo");
|
||||
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
|
||||
|
||||
repository.save(sampleEntity);
|
||||
|
||||
documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity2 = new SampleEntity();
|
||||
sampleEntity2.setId(documentId);
|
||||
sampleEntity2.setType("test");
|
||||
sampleEntity2.setRate(10);
|
||||
sampleEntity2.setMessage("foo");
|
||||
sampleEntity2.setLocation(new GeoPoint(30.7806d, 0.0875d));
|
||||
|
||||
repository.save(sampleEntity2);
|
||||
|
||||
// when
|
||||
long count = repository.countByLocationNear(new Point(3.0875d, 45.7806d), new Distance(2, Metrics.KILOMETERS));
|
||||
// then
|
||||
assertThat(count, is(equalTo(1L)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+11
@@ -24,6 +24,8 @@ import javax.inject.Inject;
|
||||
class CdiRepositoryClient {
|
||||
|
||||
private CdiProductRepository repository;
|
||||
private SamplePersonRepository samplePersonRepository;
|
||||
|
||||
|
||||
public CdiProductRepository getRepository() {
|
||||
return repository;
|
||||
@@ -33,4 +35,13 @@ class CdiRepositoryClient {
|
||||
public void setRepository(CdiProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public SamplePersonRepository getSamplePersonRepository() {
|
||||
return samplePersonRepository;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setSamplePersonRepository(SamplePersonRepository samplePersonRepository) {
|
||||
this.samplePersonRepository = samplePersonRepository;
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repositories.cdi;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.webbeans.cditest.CdiTestContainer;
|
||||
@@ -33,6 +34,7 @@ public class CdiRepositoryTests {
|
||||
|
||||
private static CdiTestContainer cdiContainer;
|
||||
private CdiProductRepository repository;
|
||||
private SamplePersonRepository personRepository;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws Exception {
|
||||
@@ -51,6 +53,7 @@ public class CdiRepositoryTests {
|
||||
public void setUp() {
|
||||
CdiRepositoryClient client = cdiContainer.getInstance(CdiRepositoryClient.class);
|
||||
repository = client.getRepository();
|
||||
personRepository = client.getSamplePersonRepository();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -80,4 +83,13 @@ public class CdiRepositoryTests {
|
||||
retrieved = repository.findOne(bean.getId());
|
||||
assertNull(retrieved);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAES-113
|
||||
*/
|
||||
@Test
|
||||
public void returnOneFromCustomImpl() {
|
||||
|
||||
assertThat(personRepository.returnOne(), is(1));
|
||||
}
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repositories.cdi;
|
||||
|
||||
import org.springframework.data.elasticsearch.entities.Person;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
* @see DATAES-113
|
||||
*/
|
||||
public interface SamplePersonRepository extends Repository<Person, Long>, SamplePersonRepositoryCustom {
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.repositories.cdi;
|
||||
|
||||
/**
|
||||
* @see DATAES-113
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
interface SamplePersonRepositoryCustom {
|
||||
|
||||
int returnOne();
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.repositories.cdi;
|
||||
|
||||
/**
|
||||
* @see DATAES-113
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class SamplePersonRepositoryImpl implements SamplePersonRepositoryCustom {
|
||||
|
||||
@Override
|
||||
public int returnOne() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
+60
-1
@@ -20,12 +20,18 @@ import java.util.List;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.elasticsearch.annotations.Query;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.entities.SampleEntity;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
* @author Mohsin Husen
|
||||
* @author Kevin Leturc
|
||||
*/
|
||||
public interface SampleCustomMethodRepository extends ElasticsearchRepository<SampleEntity, String> {
|
||||
|
||||
@@ -57,11 +63,64 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository<Sa
|
||||
|
||||
Page<SampleEntity> findByIdIn(List<String> ids, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByIdNotIn(List<String> messages, Pageable pageable);
|
||||
Page<SampleEntity> findByIdNotIn(List<String> ids, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByAvailableTrue(Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByAvailableFalse(Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByMessageOrderByTypeAsc(String message, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationWithin(GeoPoint point, String distance, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationWithin(Point point, Distance distance, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationNear(GeoBox box, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationNear(Box box, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationNear(Point point, Distance distance, Pageable pageable);
|
||||
|
||||
Page<SampleEntity> findByLocationNear(GeoPoint point, String distance, Pageable pageable);
|
||||
|
||||
long countByType(String type);
|
||||
|
||||
long countByTypeNot(String type);
|
||||
|
||||
long countByAvailable(boolean available);
|
||||
|
||||
long countByRateLessThan(int rate);
|
||||
|
||||
long countByRateBefore(int rate);
|
||||
|
||||
long countByRateAfter(int rate);
|
||||
|
||||
long countByMessageLike(String message);
|
||||
|
||||
long countByMessageStartingWith(String message);
|
||||
|
||||
long countByMessageEndingWith(String message);
|
||||
|
||||
long countByMessageContaining(String message);
|
||||
|
||||
long countByIdIn(List<String> ids);
|
||||
|
||||
long countByIdNotIn(List<String> ids);
|
||||
|
||||
long countByAvailableTrue();
|
||||
|
||||
long countByAvailableFalse();
|
||||
|
||||
long countByLocationWithin(GeoPoint point, String distance);
|
||||
|
||||
long countByLocationWithin(Point point, Distance distance);
|
||||
|
||||
long countByLocationNear(GeoBox box);
|
||||
|
||||
long countByLocationNear(Box box);
|
||||
|
||||
long countByLocationNear(Point point, Distance distance);
|
||||
|
||||
long countByLocationNear(GeoPoint point, String distance);
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -121,7 +121,7 @@ public class DynamicSettingAndMappingEntityRepositoryTests {
|
||||
assertThat(mapping, is(notNullValue()));
|
||||
assertThat(properties, is(notNullValue()));
|
||||
assertThat(((String) ((Map) properties.get("email")).get("type")), is("string"));
|
||||
assertThat((String) ((Map)properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
assertThat((String) ((Map) properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,7 +146,7 @@ public class DynamicSettingAndMappingEntityRepositoryTests {
|
||||
assertThat(mapping, is(notNullValue()));
|
||||
assertThat(properties, is(notNullValue()));
|
||||
assertThat(((String) ((Map) properties.get("email")).get("type")), is("string"));
|
||||
assertThat((String) ((Map)properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
assertThat((String) ((Map) properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -162,6 +162,6 @@ public class DynamicSettingAndMappingEntityRepositoryTests {
|
||||
assertThat(mapping, is(notNullValue()));
|
||||
assertThat(properties, is(notNullValue()));
|
||||
assertThat(((String) ((Map) properties.get("email")).get("type")), is("string"));
|
||||
assertThat((String) ((Map)properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
assertThat((String) ((Map) properties.get("email")).get("analyzer"), is("emailAnalyzer"));
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repositories.spel;
|
||||
|
||||
import org.springframework.data.elasticsearch.entities.SpELEntity;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
|
||||
/**
|
||||
* SpELRepository
|
||||
*
|
||||
* @author Artur Konczak
|
||||
*
|
||||
*/
|
||||
public interface SpELRepository extends ElasticsearchRepository<SpELEntity, String> {
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repository.support;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
/**
|
||||
* @author Florian Hopf
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ElasticsearchEntityInformationCreatorImplTest {
|
||||
|
||||
@Mock
|
||||
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
||||
@Mock
|
||||
private ElasticsearchPersistentEntity<String> persistentEntity;
|
||||
private ElasticsearchEntityInformationCreatorImpl entityInfoCreator;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
entityInfoCreator = new ElasticsearchEntityInformationCreatorImpl(mappingContext);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowIllegalArgumentExceptionOnMissingEntity() {
|
||||
entityInfoCreator.getEntityInformation(String.class);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowIllegalArgumentExceptionOnMissingIdAnnotation() {
|
||||
doReturn(persistentEntity).when(mappingContext).getPersistentEntity(String.class);
|
||||
doReturn(String.class).when(persistentEntity).getType();
|
||||
doReturn(null).when(persistentEntity).getIdProperty();
|
||||
entityInfoCreator.getEntityInformation(String.class);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
{
|
||||
"test-setting-type" : {
|
||||
"properties" : {
|
||||
"email" : {"type" : "string", "analyzer" : "emailAnalyzer" }
|
||||
"test-setting-type": {
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"analyzer": "emailAnalyzer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||
|
||||
<import resource="infrastructure.xml"/>
|
||||
|
||||
<bean name="elasticsearchTemplate"
|
||||
class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
|
||||
<constructor-arg name="client" ref="client"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<elasticsearch:repositories
|
||||
base-package="org.springframework.data.elasticsearch.repositories.spel"/>
|
||||
|
||||
</beans>
|
||||
+2
-2
@@ -11,8 +11,8 @@ Import-Template:
|
||||
org.apache.commons.collections.*;version="${commonscollections:[=.=.=,+1.0.0)}";resolution:=optional,
|
||||
org.apache.commons.lang.*;version="${commonslang:[=.=.=,+1.0.0)}",
|
||||
com.fasterxml.jackson.*;version="${jackson:[=.=.=,+1.0.0)}";resolution:=optional,
|
||||
org.elasticsearch.*;version="${elasticsearch:[=.=.=,+1.1.1)}",
|
||||
org.apache.lucene.*;version="4.7.2",
|
||||
org.elasticsearch.*;version="${elasticsearch:[=.=.=,+1.2.1)}",
|
||||
org.apache.lucene.*;version="4.8.1",
|
||||
org.joda.time.*;version="${jodatime:[=.=.=,+1.0.0)}",
|
||||
org.slf4j.*;version="${slf4j:[=.=.=,+1.0.0)}",
|
||||
org.springframework.*;version="${spring:[=.=.=.=,+1.0.0)}",
|
||||
|
||||
Reference in New Issue
Block a user