1
0
mirror of synced 2026-07-07 10:40:02 +00:00

Compare commits

..

27 Commits

Author SHA1 Message Date
John Blum 54b7378c1c Upgrade to new spring.io project pages format. 2018-10-10 22:07:44 -07:00
Mark Paluch 3a5cdde67f Add defensive check for empty repository key 2017-03-31 11:38:51 +02:00
Mark Paluch f7aafb1a40 Switch markdown engine to kramdown. 2016-04-07 09:50:18 +02:00
Artur Konczak 83595685c3 Merge pull request #142 from mp911de/issue/DATAES-246
DATAES-246 - Remove links to forum.spring.io.
2016-03-31 21:33:52 +01:00
Mark Paluch aaa351b1d2 DATAES-246 - Remove links to forum.spring.io.
Fix also base-url and highlighting of symbol names.
2016-03-31 17:27:29 +02:00
Artur Konczak ceca280868 initial version for spring-date-elasticsearchgit 2016-02-24 16:45:04 +00:00
Brian Clozel d25f656a48 Fix content warning issues over https
When served with HTTP/2 and TLS, project pages show several mixed
content errors:

* the imported Google fonts
* the AJAX call to spring.io to get the current project information
* the newsletter iframe

This commit changes URLs to use https or protocol-relative URLs when
possible. This also deletes the now defunct newsletter integration.
2015-12-16 14:23:00 +01:00
Brian Clozel 8227656cb0 Merge pull request #12 from gregturn/gh-6
Conditionalize reference doc/api doc links
2015-08-18 18:38:06 +02:00
Greg Turnquist 086e2b3d2b Conditionalize showing reference doc/api doc links
If the reference doc URL of the API doc URL is empty, don't display a hyperlink.
2015-08-04 08:12:53 -07:00
Brian Clozel 7d63246f6b Revert "Display Pivotal Education related courseware"
This reverts commit bf15ee8a6d.
2015-07-16 18:56:19 +02:00
Brian Clozel bf15ee8a6d Display Pivotal Education related courseware
This change adds a new "Related Courseware" section in the side
container; this section lists links to courses and talks that are
relevant to the current project page.

Relevant content is fetched by the browser, with an AJAX request sent to
the Pivotal Education LMS API. This API uses the Referrer HTTP header as
input parameter to its content selection algorithm.

Note that CORS HTTP headers are also used to allow/disallow AJAX cross
domain requests.
2015-03-09 11:58:27 +01:00
Brian Clozel 1690b17cb4 Merge pull request #9 from dsyer/patch-2
Gem installation instructions updated
2014-10-20 10:25:27 +02:00
Dave Syer fc0cf54962 Add "gem install bundler" for people using vanilla Ruby 2014-09-30 11:36:48 +01:00
Brian Clozel 650b0f71b1 Merge pull request #10 from dsyer/patch-3
Fix directory name for sample pages
2014-09-30 11:55:08 +02:00
Dave Syer b67c026a16 Fix directory name for sample pages 2014-09-30 09:43:46 +01:00
Dave Syer ccb4a8a2bb Gem installation instructions updated
Using "gem install" didn't work for me because of the Gemfile.lock that is in source control (presumably for a reason).
2014-09-30 09:37:55 +01:00
Brian Clozel 1a150a334a Merge pull request #8 from dsyer/patch-1
Fix "rm -rf" instruictions
2014-09-30 10:13:28 +02:00
Dave Syer c340c6914f Fix "rm -rf" instruictions
Existing copy is wrong because "git rm -rf *" fails if there are any untracked files (e.g. target/). Changed to "git rm -rf `git ls-files`".
2014-09-30 09:09:50 +01:00
Brian Clozel 77167c0d39 Fix company name and website in footer 2014-09-22 18:52:09 +02:00
Brian Clozel 1ca26dffbf Merge pull request #7 from bclozel/forum
Update navbar item "Forum" -> "Questions"
2014-09-22 18:42:32 +02:00
Brian Clozel 56978cfc90 Change Forum navbar item to Questions
The projects navbar should mirror the one on the spring.io website.
2014-09-03 23:01:21 +02:00
Brian Clozel 9c7287c64f Merge pull request #4 from bclozel/zclip
Fix ZeroClipboard integration in gh-pages
2014-06-19 21:38:06 +02:00
Chris Beams 34fb3af7d3 Merge pull request #5 from wilkinsona/optional-forum-link
Make the link to a project's forum optional
2014-05-13 18:20:08 +02:00
Andy Wilkinson 7e6493ef7b Make the link to a project's forum optional
Omit the link to the forum if the project's metadata does not provide
a forum url
2014-05-13 16:22:19 +01:00
Brian Clozel 92c5b852c1 Add missing ZeroClipbpard SWF file
Flash support for ZeroClipboard is not working in project pages since
the SWF file is missing. There was a typo in the .gitignore file that
ignored "*.sw?" files.
2014-04-15 14:54:48 +02:00
Phillip Webb 85ed196cf4 Remove 'not found in _includes' hacks
Remove the use if "unless contains 'not found in _includes directory'"
hacks that were previously used to detect when _includes were missing.

This change is required as the hack no longer works with the latest
Jekyll release (and therefore also with GitHub).

Additional 'custom_pom_template' and 'custom_gradle_template' flags
must now be set in _config.yml if you want to include a custom pom.xml
or build.gradle file.
2013-11-14 10:11:34 -08:00
Phillip Webb 171918e41a Initialize shared gh-pages infrastructure 2013-09-09 01:41:47 -07:00
307 changed files with 18 additions and 28913 deletions
-12
View File
@@ -1,12 +0,0 @@
<!--
Thank you for proposing a pull request. This template will guide you through the essential steps necessary for a pull request.
Make sure that:
-->
- [ ] You have read the [Spring Data contribution guidelines](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc).
- [ ] There is a ticket in the bug tracker for the project in our [JIRA](https://jira.spring.io/browse/DATAES).
- [ ] You use the code formatters provided [here](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide) and have them applied to your changes. Dont submit any formatting related changes.
- [ ] You submit test cases (unit or integration tests) that back your changes.
- [ ] You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).
+7 -17
View File
@@ -1,18 +1,8 @@
atlassian-ide-plugin.xml
## Ignore svn files
.svn
## ignore any target dir
target
## Ignore project files created by Eclipse
.settings
.project
.classpath
## Ignore project files created by IntelliJ IDEA
*.iml
*.ipr
*.iws
#*
.#*
*~
_site
.idea
*.sw[op]
.project
sample-pages
-27
View File
@@ -1,27 +0,0 @@
= Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses,
without explicit permission
* Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io.
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
This Code of Conduct is adapted from the http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/].
-3
View File
@@ -1,3 +0,0 @@
= Spring Data contribution guidelines
You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc[here].
-255
View File
@@ -1,255 +0,0 @@
Spring Data Elasticsearch
=========================
Spring Data implementation for ElasticSearch
Spring Data makes it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services as well as provide improved support for relational database technologies.
The Spring Data Elasticsearch project provides integration with the [elasticsearch](http://www.elasticsearch.org/) search engine.
Guide
------------
* [Reference Documentation](http://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/)
* [API Documentation](http://docs.spring.io/spring-data/elasticsearch/docs/current/api/)
* [Spring Data Project](http://projects.spring.io/spring-data)
* [Sample Test Application](https://github.com/BioMedCentralLtd/spring-data-elasticsearch-sample-application)
* [Issues](https://jira.springsource.org/browse/DATAES)
* [Spring Data Elasticsearch Google Group](https://groups.google.com/d/forum/spring-data-elasticsearch-devs)
* [Questions](http://stackoverflow.com/questions/tagged/spring-data-elasticsearch)
Quick Start
-----------
Wiki page for [Getting Started](https://github.com/spring-projects/spring-data-elasticsearch/wiki/How-to-start-with-spring-data-elasticsearch)
### Maven configuration
Add the Maven dependency:
```xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>x.y.z.RELEASE</version>
</dependency>
```
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare
the appropriate dependency version.
```xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>x.y.z.BUILD-SNAPSHOT</version>
</dependency>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>http://repo.spring.io/libs-snapshot</url>
</repository>
```
| spring data elasticsearch | elasticsearch |
|:-----------------------------------:|:-------------:|
| 3.0.0.RC2 | 5.5.0 |
| 3.0.0.M4 | 5.4.0 |
| 2.0.4.RELEASE | 2.4.0 |
| 2.0.0.RELEASE | 2.2.0 |
| 1.4.0.M1 | 1.7.3 |
| 1.3.0.RELEASE | 1.5.2 |
| 1.2.0.RELEASE | 1.4.4 |
| 1.1.0.RELEASE | 1.3.2 |
| 1.0.0.RELEASE | 1.1.1 |
### 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.
The ElasticsearchCrudRepository extends PagingAndSortingRepository
```java
public interface ElasticsearchCrudRepository<T, ID extends Serializable> extends ElasticsearchRepository<T, ID>, PagingAndSortingRepository<T, ID> {
}
```
Extending ElasticsearchRepository for custom methods
```java
public interface BookRepository extends Repository<Book, String> {
List<Book> findByNameAndPrice(String name, Integer price);
List<Book> findByNameOrPrice(String name, Integer price);
Page<Book> findByName(String name,Pageable page);
Page<Book> findByNameNot(String name,Pageable page);
Page<Book> findByPriceBetween(int price,Pageable page);
Page<Book> findByNameLike(String name,Pageable page);
@Query("{\"bool\" : {\"must\" : {\"term\" : {\"message\" : \"?0\"}}}}")
Page<Book> findByMessage(String message, Pageable pageable);
}
```
Indexing a single document with Repository
```java
@Autowired
private SampleElasticsearchRepository repository;
String documentId = "123456";
SampleEntity sampleEntity = new SampleEntity();
sampleEntity.setId(documentId);
sampleEntity.setMessage("some message");
repository.save(sampleEntity);
```
Indexing multiple Document(bulk index) using Repository
```java
@Autowired
private SampleElasticsearchRepository repository;
String documentId = "123456";
SampleEntity sampleEntity1 = new SampleEntity();
sampleEntity1.setId(documentId);
sampleEntity1.setMessage("some message");
String documentId2 = "123457"
SampleEntity sampleEntity2 = new SampleEntity();
sampleEntity2.setId(documentId2);
sampleEntity2.setMessage("test message");
List<SampleEntity> sampleEntities = Arrays.asList(sampleEntity1, sampleEntity2);
//bulk index
repository.save(sampleEntities);
```
### ElasticsearchTemplate
ElasticsearchTemplate is the central support class for elasticsearch operations.
Indexing a single document using Elasticsearch Template
```java
String documentId = "123456";
SampleEntity sampleEntity = new SampleEntity();
sampleEntity.setId(documentId);
sampleEntity.setMessage("some message");
IndexQuery indexQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build();
elasticsearchTemplate.index(indexQuery);
```
Indexing multiple Document(bulk index) using Elasticsearch Template
```java
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
//first document
String documentId = "123456";
SampleEntity sampleEntity1 = new SampleEntity();
sampleEntity1.setId(documentId);
sampleEntity1.setMessage("some message");
IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build();
indexQueries.add(indexQuery1);
//second document
String documentId2 = "123457";
SampleEntity sampleEntity2 = new SampleEntity();
sampleEntity2.setId(documentId2);
sampleEntity2.setMessage("some message");
IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build()
indexQueries.add(indexQuery2);
//bulk index
elasticsearchTemplate.bulkIndex(indexQueries);
```
Searching entities using Elasticsearch Template
```java
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryString(documentId).field("id"))
.build();
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
```
### XML Namespace
You can set up repository scanning via xml configuration, which will happily create your repositories.
Using Node Client
```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/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<elasticsearch:node-client id="client" local="true"/>
<bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg name="client" ref="client"/>
</bean>
</beans>
```
Using Transport Client
```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/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<elasticsearch:repositories base-package="com.xyz.acme"/>
<elasticsearch:transport-client id="client" cluster-nodes="ip:9300,ip:9300" cluster-name="elasticsearch" />
<bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg name="client" ref="client"/>
</bean>
</beans>
```
## Help Pages
* [Geo distance and location search](https://github.com/spring-projects/spring-data-elasticsearch/wiki/Geo-indexing-and-request)
* [Custom object mapper](https://github.com/spring-projects/spring-data-elasticsearch/wiki/Custom-ObjectMapper)
## Contributing to Spring Data
Here are some ways for you to get involved in the community:
* Get involved with the Spring community on Stack OverFlow. Please help out on the [forum](https://stackoverflow.com/questions/tagged/spring-data-elasticsearch) by responding to questions and joining the debate.
* Create [JIRA](https://jira.spring.io/browse/DATAES/) tickets for bugs and new features and comment and vote on the ones that you are interested in.
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](http://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
* Watch for upcoming articles on Spring by [subscribing](http://www.springsource.org/node/feed) to springframework.org
Before we accept a non-trivial patch or pull request we will need you to [sign the Contributor License Agreement](https://cla.pivotal.io/sign/spring). Signing the contributors agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. If you forget to do so, you'll be reminded when you submit a pull request. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
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.adoc)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+11
View File
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="http://spring.io/projects/spring-data-elasticsearch">
<meta http-equiv="refresh" content="0; url=http://spring.io/projects/spring-data-elasticsearch">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="http://spring.io/projects/spring-data-elasticsearch">Click here if you are not redirected.</a>
<script>location="http://spring.io/projects/spring-data-elasticsearch"</script>
</html>
-255
View File
@@ -1,255 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.0.3.RELEASE</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<name>Spring Data Elasticsearch</name>
<description>Spring Data Implementation for Elasticsearch</description>
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties>
<commonscollections>3.2.1</commonscollections>
<commonslang>2.6</commonslang>
<elasticsearch>5.5.0</elasticsearch>
<log4j>2.8.2</log4j>
<springdata.commons>2.0.3.RELEASE</springdata.commons>
<java-module-name>spring.data.elasticsearch</java-module-name>
</properties>
<dependencies>
<!-- 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>
<!-- 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>
<!-- 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>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>${elasticsearch}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j}</version>
<scope>test</scope>
</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>
<!-- Test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.openwebbeans.test</groupId>
<artifactId>cditest-owb</artifactId>
<version>1.2.8</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_1.0_spec</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-atinject_1.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Upgrade xbean to 4.5 to prevent incompatibilities due to ASM versions -->
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-asm5-shaded</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- required by elasticsearch -->
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok}</version>
<scope>test</scope>
</dependency>
</dependencies>
<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.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<developers>
<developer>
<id>biomedcentral</id>
<name>BioMed Central Development Team</name>
<timezone>+0</timezone>
</developer>
</developers>
<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>https://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>
<ciManagement>
<system>Bamboo</system>
<url>https://build.spring.io/browse/SPRINGDATAES</url>
</ciManagement>
<issueManagement>
<system>JIRA</system>
<url>https://jira.spring.io/browse/DATAES</url>
</issueManagement>
</project>
-36
View File
@@ -1,36 +0,0 @@
= Spring Data Elasticsearch
BioMed Central Development Team
:revnumber: {version}
:revdate: {localdate}
:toc:
:toc-placement!:
:spring-data-commons-docs: ../../../../spring-data-commons/src/main/asciidoc
(C) 2013-2015 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[]
include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[]
:leveloffset: -1
-20
View File
@@ -1,20 +0,0 @@
= 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
@@ -1,288 +0,0 @@
[[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);
}
----
====
@@ -1,72 +0,0 @@
[[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;
}
}
}
----
====
@@ -1,51 +0,0 @@
/*
* 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;
import java.util.Map;
/**
* ElasticsearchException
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class ElasticsearchException extends RuntimeException {
private Map<String, String> failedDocuments;
public ElasticsearchException(String message) {
super(message);
}
public ElasticsearchException(String message, Throwable cause) {
super(message, cause);
}
public ElasticsearchException(String message, Throwable cause, Map<String, String> failedDocuments) {
super(message, cause);
this.failedDocuments = failedDocuments;
}
public ElasticsearchException(String message, Map<String, String> failedDocuments) {
super(message);
this.failedDocuments = failedDocuments;
}
public Map<String, String> getFailedDocuments() {
return failedDocuments;
}
}
@@ -1,40 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
/**
* Based on the reference doc - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
*
* @author Mewes Kochheim
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface CompletionField {
String searchAnalyzer() default "simple";
String analyzer() default "simple";
boolean preserveSeparators() default true;
boolean preservePositionIncrements() default true;
int maxInputLength() default 50;
}
@@ -1,31 +0,0 @@
/*
* 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.annotations;
/**
* @author Jakub Vavrik
* Values based on reference doc - http://www.elasticsearch.org/guide/reference/mapping/date-format/
*/
public enum DateFormat {
none, custom, basic_date, basic_date_time, basic_date_time_no_millis, basic_ordinal_date, basic_ordinal_date_time,
basic_ordinal_date_time_no_millis, basic_time, basic_time_no_millis, basic_t_time, basic_t_time_no_millis,
basic_week_date, basic_week_date_time, basic_week_date_time_no_millis, date, date_hour, date_hour_minute,
date_hour_minute_second, date_hour_minute_second_fraction, date_hour_minute_second_millis, date_optional_time,
date_time, date_time_no_millis, hour, hour_minute, hour_minute_second, hour_minute_second_fraction,
hour_minute_second_millis, ordinal_date, ordinal_date_time, ordinal_date_time_no_millis, time, time_no_millis,
t_time, t_time_no_millis, week_date, week_date_time, weekDateTimeNoMillis, week_year, weekyearWeek,
weekyearWeekDay, year, year_month, year_month_day
}
@@ -1,51 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
import org.springframework.data.annotation.Persistent;
/**
* Document
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mason Chan
*/
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
String indexName();
String type() default "";
boolean useServerConfiguration() default false;
short shards() default 5;
short replicas() default 1;
String refreshInterval() default "1s";
String indexStoreType() default "fs";
boolean createIndex() default true;
}
@@ -1,58 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
* @author Jakub Vavrik
* @author Kevin Leturc
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface Field {
FieldType type() default FieldType.Auto;
boolean index() default true;
DateFormat format() default DateFormat.none;
String pattern() default "";
boolean store() default false;
boolean fielddata() default false;
String searchAnalyzer() default "";
String analyzer() default "";
String[] ignoreFields() default {};
boolean includeInParent() default false;
}
@@ -1,26 +0,0 @@
/*
* 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.annotations;
/**
* @author Artur Konczak
* @author Mohsin Husen
* @author Alexander Volz
* @author Dennis Maaß
*/
public enum FieldIndex {
not_analyzed, analyzed, no
}
@@ -1,25 +0,0 @@
/*
* 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.annotations;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
*/
public enum FieldType {
text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, keyword
}
@@ -1,28 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
/**
* @author Artur Konczak
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface GeoPointField {
}
@@ -1,43 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InnerField {
String suffix();
FieldType type();
boolean index() default true;
boolean store() default false;
boolean fielddata() default false;
String searchAnalyzer() default "";
String indexAnalyzer() default "";
}
@@ -1,34 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
import org.springframework.data.annotation.Persistent;
/**
* Elasticsearch Mapping
*
* @author Mohsin Husen
*/
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Mapping {
String mappingPath() default "";
}
@@ -1,34 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface MultiField {
public Field mainField();
public InnerField[] otherFields() default {};
}
@@ -1,35 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
import org.springframework.data.annotation.Persistent;
/**
* Parent
*
* @author Philipp Jardas
*/
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Parent {
String type();
}
@@ -1,45 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
/**
* Query
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Query {
/**
* Elasticsearch query to be used when executing query. May contain placeholders eg. ?0
*
* @return
*/
String value() default "";
/**
* Named Query Named looked up by repository.
*
* @return
*/
String name() default "";
}
@@ -1,19 +0,0 @@
package org.springframework.data.elasticsearch.annotations;
import java.lang.annotation.*;
/**
* @author Ryan Murfitt
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface ScriptedField {
/**
* (Optional) The name of the scripted field. Defaults to
* the field name.
*/
String name() default "";
}
@@ -1,36 +0,0 @@
/*
* 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.annotations;
import java.lang.annotation.*;
import org.springframework.data.annotation.Persistent;
/**
* Elasticsearch Setting
*
* @author Mohsin Husen
*/
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Setting {
String settingPath() default "";
}
@@ -1,144 +0,0 @@
/*
* Copyright 2015-2017 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.client;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.InternalSettingsPreparer;
import org.elasticsearch.node.Node;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.transport.Netty4Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import static java.util.Arrays.*;
/**
* NodeClientFactoryBean
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class NodeClientFactoryBean implements FactoryBean<Client>, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(NodeClientFactoryBean.class);
private boolean local;
private boolean enableHttp;
private String clusterName;
private NodeClient nodeClient;
private String pathData;
private String pathHome;
private String pathConfiguration;
public static class TestNode extends Node {
public TestNode(Settings preparedSettings, Collection<Class<? extends Plugin>> classpathPlugins) {
super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, null), classpathPlugins);
}
}
NodeClientFactoryBean() {
}
public NodeClientFactoryBean(boolean local) {
this.local = local;
}
@Override
public NodeClient getObject() throws Exception {
return nodeClient;
}
@Override
public Class<? extends Client> getObjectType() {
return NodeClient.class;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void afterPropertiesSet() throws Exception {
nodeClient = (NodeClient) new TestNode(
Settings.builder().put(loadConfig())
.put("transport.type", "netty4")
.put("transport.type", "local")
.put("http.type", "netty4")
.put("path.home", this.pathHome)
.put("path.data", this.pathData)
.put("cluster.name", this.clusterName)
.put("node.max_local_storage_nodes", 100)
.put("script.inline", "true")
.build(), asList(Netty4Plugin.class)).start().client();
}
private Settings loadConfig() throws IOException {
if (StringUtils.isNotBlank(pathConfiguration)) {
InputStream stream = getClass().getClassLoader().getResourceAsStream(pathConfiguration);
if (stream != null) {
return Settings.builder().loadFromStream(pathConfiguration, getClass().getClassLoader().getResourceAsStream(pathConfiguration)).build();
}
logger.error(String.format("Unable to read node configuration from file [%s]", pathConfiguration));
}
return Settings.builder().build();
}
public void setLocal(boolean local) {
this.local = local;
}
public void setEnableHttp(boolean enableHttp) {
this.enableHttp = enableHttp;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public void setPathData(String pathData) {
this.pathData = pathData;
}
public void setPathHome(String pathHome) {
this.pathHome = pathHome;
}
public void setPathConfiguration(String configuration) {
this.pathConfiguration = configuration;
}
@Override
public void destroy() throws Exception {
try {
logger.info("Closing elasticSearch client");
if (nodeClient != null) {
nodeClient.close();
}
} catch (final Exception e) {
logger.error("Error closing ElasticSearch client: ", e);
}
}
}
@@ -1,156 +0,0 @@
/*
* 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.client;
import static org.apache.commons.lang.StringUtils.*;
import java.net.InetAddress;
import java.util.Properties;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
/**
* TransportClientFactoryBean
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Jakub Vavrik
* @author Piotr Betkier
*/
public class TransportClientFactoryBean implements FactoryBean<TransportClient>, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(TransportClientFactoryBean.class);
private String clusterNodes = "127.0.0.1:9300";
private String clusterName = "elasticsearch";
private Boolean clientTransportSniff = true;
private Boolean clientIgnoreClusterName = Boolean.FALSE;
private String clientPingTimeout = "5s";
private String clientNodesSamplerInterval = "5s";
private TransportClient client;
private Properties properties;
static final String COLON = ":";
static final String COMMA = ",";
@Override
public void destroy() throws Exception {
try {
logger.info("Closing elasticSearch client");
if (client != null) {
client.close();
}
} catch (final Exception e) {
logger.error("Error closing ElasticSearch client: ", e);
}
}
@Override
public TransportClient getObject() throws Exception {
return client;
}
@Override
public Class<TransportClient> getObjectType() {
return TransportClient.class;
}
@Override
public boolean isSingleton() {
return false;
}
@Override
public void afterPropertiesSet() throws Exception {
buildClient();
}
protected void buildClient() throws Exception {
client = new PreBuiltTransportClient(settings());
Assert.hasText(clusterNodes, "[Assertion failed] clusterNodes settings missing.");
for (String clusterNode : split(clusterNodes, COMMA)) {
String hostName = substringBeforeLast(clusterNode, COLON);
String port = substringAfterLast(clusterNode, COLON);
Assert.hasText(hostName, "[Assertion failed] missing host name in 'clusterNodes'");
Assert.hasText(port, "[Assertion failed] missing port in 'clusterNodes'");
logger.info("adding transport node : " + clusterNode);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port)));
}
client.connectedNodes();
}
private Settings settings() {
if (properties != null) {
return Settings.builder().put(properties).build();
}
return Settings.builder()
.put("cluster.name", clusterName)
.put("client.transport.sniff", clientTransportSniff)
.put("client.transport.ignore_cluster_name", clientIgnoreClusterName)
.put("client.transport.ping_timeout", clientPingTimeout)
.put("client.transport.nodes_sampler_interval", clientNodesSamplerInterval)
.build();
}
public void setClusterNodes(String clusterNodes) {
this.clusterNodes = clusterNodes;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public void setClientTransportSniff(Boolean clientTransportSniff) {
this.clientTransportSniff = clientTransportSniff;
}
public String getClientNodesSamplerInterval() {
return clientNodesSamplerInterval;
}
public void setClientNodesSamplerInterval(String clientNodesSamplerInterval) {
this.clientNodesSamplerInterval = clientNodesSamplerInterval;
}
public String getClientPingTimeout() {
return clientPingTimeout;
}
public void setClientPingTimeout(String clientPingTimeout) {
this.clientPingTimeout = clientPingTimeout;
}
public Boolean getClientIgnoreClusterName() {
return clientIgnoreClusterName;
}
public void setClientIgnoreClusterName(Boolean clientIgnoreClusterName) {
this.clientIgnoreClusterName = clientIgnoreClusterName;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
@@ -1,41 +0,0 @@
/*
* 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.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.data.elasticsearch.repository.config.ElasticsearchRepositoryConfigExtension;
import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
* ElasticsearchNamespaceHandler
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class ElasticsearchNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
RepositoryConfigurationExtension extension = new ElasticsearchRepositoryConfigExtension();
RepositoryBeanDefinitionParser parser = new RepositoryBeanDefinitionParser(extension);
registerBeanDefinitionParser("repositories", parser);
registerBeanDefinitionParser("node-client", new NodeClientBeanDefinitionParser());
registerBeanDefinitionParser("transport-client", new TransportClientBeanDefinitionParser());
}
}
@@ -1,57 +0,0 @@
/*
* Copyright 2015 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.config;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.elasticsearch.client.NodeClientFactoryBean;
import org.w3c.dom.Element;
/**
* NodeClientBeanDefinitionParser
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class NodeClientBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(NodeClientFactoryBean.class);
setLocalSettings(element, builder);
return getSourcedBeanDefinition(builder, element, parserContext);
}
private void setLocalSettings(Element element, BeanDefinitionBuilder builder) {
builder.addPropertyValue("local", Boolean.valueOf(element.getAttribute("local")));
builder.addPropertyValue("clusterName", element.getAttribute("cluster-name"));
builder.addPropertyValue("enableHttp", Boolean.valueOf(element.getAttribute("http-enabled")));
builder.addPropertyValue("pathData", element.getAttribute("path-data"));
builder.addPropertyValue("pathHome", element.getAttribute("path-home"));
builder.addPropertyValue("pathConfiguration", element.getAttribute("path-configuration"));
}
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
ParserContext context) {
AbstractBeanDefinition definition = builder.getBeanDefinition();
definition.setSource(context.extractSource(source));
return definition;
}
}
@@ -1,56 +0,0 @@
/*
* 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.config;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.elasticsearch.client.TransportClientFactoryBean;
import org.w3c.dom.Element;
/**
* TransportClientBeanDefinitionParser
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class TransportClientBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TransportClientFactoryBean.class);
setConfigurations(element, builder);
return getSourcedBeanDefinition(builder, element, parserContext);
}
private void setConfigurations(Element element, BeanDefinitionBuilder builder) {
builder.addPropertyValue("clusterNodes", element.getAttribute("cluster-nodes"));
builder.addPropertyValue("clusterName", element.getAttribute("cluster-name"));
builder.addPropertyValue("clientTransportSniff", Boolean.valueOf(element.getAttribute("client-transport-sniff")));
builder.addPropertyValue("clientIgnoreClusterName", Boolean.valueOf(element.getAttribute("client-transport-ignore-cluster-name")));
builder.addPropertyValue("clientPingTimeout", element.getAttribute("client-transport-ping-timeout"));
builder.addPropertyValue("clientNodesSamplerInterval", element.getAttribute("client-transport-nodes-sampler-interval"));
}
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
ParserContext context) {
AbstractBeanDefinition definition = builder.getBeanDefinition();
definition.setSource(context.extractSource(source));
return definition;
}
}
@@ -1,50 +0,0 @@
/*
* 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;
import static org.apache.commons.lang.StringUtils.*;
import java.io.IOException;
import org.springframework.data.elasticsearch.ElasticsearchException;
/**
* @author Artur Konczak
*/
public abstract class AbstractResultMapper implements ResultsMapper {
private EntityMapper entityMapper;
public AbstractResultMapper(EntityMapper entityMapper) {
this.entityMapper = entityMapper;
}
public <T> T mapEntity(String source, Class<T> clazz) {
if (isBlank(source)) {
return null;
}
try {
return entityMapper.mapToObject(source, clazz);
} catch (IOException e) {
throw new ElasticsearchException("failed to map source [ " + source + "] to class " + clazz.getSimpleName(), e);
}
}
@Override
public EntityMapper getEntityMapper() {
return this.entityMapper;
}
}
@@ -1,245 +0,0 @@
/*
* Copyright 2013-2017 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 static org.springframework.data.elasticsearch.core.query.Criteria.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.index.query.*;
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;
/**
* CriteriaFilterProcessor
*
* @author Franck Marchand
* @author Mohsin Husen
* @author Artur Konczak
*
*/
class CriteriaFilterProcessor {
QueryBuilder createFilterFromCriteria(Criteria criteria) {
List<QueryBuilder> fbList = new LinkedList<>();
QueryBuilder filter = null;
ListIterator<Criteria> chainIterator = criteria.getCriteriaChain().listIterator();
while (chainIterator.hasNext()) {
QueryBuilder fb = null;
Criteria chainedCriteria = chainIterator.next();
if (chainedCriteria.isOr()) {
fb = QueryBuilders.boolQuery();
for(QueryBuilder f: createFilterFragmentForCriteria(chainedCriteria)){
((BoolQueryBuilder)fb).should(f);
}
fbList.add(fb);
} else if (chainedCriteria.isNegating()) {
List<QueryBuilder> negationFilters = buildNegationFilter(criteria.getField().getName(), criteria.getFilterCriteriaEntries().iterator());
if (!negationFilters.isEmpty()) {
fbList.addAll(negationFilters);
}
} else {
fbList.addAll(createFilterFragmentForCriteria(chainedCriteria));
}
}
if (!fbList.isEmpty()) {
if (fbList.size() == 1) {
filter = fbList.get(0);
} else {
filter = QueryBuilders.boolQuery();
for(QueryBuilder f: fbList) {
((BoolQueryBuilder)filter).must(f);
}
}
}
return filter;
}
private List<QueryBuilder> createFilterFragmentForCriteria(Criteria chainedCriteria) {
Iterator<Criteria.CriteriaEntry> it = chainedCriteria.getFilterCriteriaEntries().iterator();
List<QueryBuilder> filterList = new LinkedList<>();
String fieldName = chainedCriteria.getField().getName();
Assert.notNull(fieldName, "Unknown field");
QueryBuilder filter = null;
while (it.hasNext()) {
Criteria.CriteriaEntry entry = it.next();
filter = processCriteriaEntry(entry.getKey(), entry.getValue(), fieldName);
filterList.add(filter);
}
return filterList;
}
private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String fieldName) {
if (value == null) {
return null;
}
QueryBuilder filter = null;
switch (key) {
case WITHIN: {
GeoDistanceQueryBuilder geoDistanceQueryBuilder = QueryBuilders.geoDistanceQuery(fieldName);
Assert.isTrue(value instanceof Object[], "Value of a geo distance filter should be an array of two values.");
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 || valArray[0] instanceof Point, "First element of a geo distance filter must be a GeoPoint, a Point or a text");
Assert.isTrue(valArray[1] instanceof String || valArray[1] instanceof Distance, "Second element of a geo distance filter must be a text or a Distance");
StringBuilder dist = new StringBuilder();
if (valArray[1] instanceof Distance) {
extractDistanceString((Distance) valArray[1], dist);
} else {
dist.append((String) valArray[1]);
}
if (valArray[0] instanceof GeoPoint) {
GeoPoint loc = (GeoPoint) valArray[0];
geoDistanceQueryBuilder.point(loc.getLat(),loc.getLon()).distance(dist.toString()).geoDistance(GeoDistance.PLANE);
} else if (valArray[0] instanceof Point) {
GeoPoint loc = GeoPoint.fromPoint((Point) valArray[0]);
geoDistanceQueryBuilder.point(loc.getLat(), loc.getLon()).distance(dist.toString()).geoDistance(GeoDistance.PLANE);
} else {
String loc = (String) valArray[0];
if (loc.contains(",")) {
String c[] = loc.split(",");
geoDistanceQueryBuilder.point(Double.parseDouble(c[0]), Double.parseDouble(c[1])).distance(dist.toString()).geoDistance(GeoDistance.PLANE);
} else {
geoDistanceQueryBuilder.geohash(loc).distance(dist.toString()).geoDistance(GeoDistance.PLANE);
}
}
filter = geoDistanceQueryBuilder;
break;
}
case BBOX: {
filter = QueryBuilders.geoBoundingBoxQuery(fieldName);
Assert.isTrue(value instanceof Object[], "Value of a boundedBy filter should be an array of one or two values.");
Object[] valArray = (Object[]) value;
Assert.noNullElements(valArray, "Geo boundedBy filter takes a not null element array as parameter.");
if (valArray.length == 1) {
//GeoEnvelop
oneParameterBBox((GeoBoundingBoxQueryBuilder) filter, valArray[0]);
} else if (valArray.length == 2) {
//2x GeoPoint
//2x text
twoParameterBBox((GeoBoundingBoxQueryBuilder) filter, valArray);
} else {
//error
Assert.isTrue(false, "Geo distance filter takes a 1-elements array(GeoBox) or 2-elements array(GeoPoints or Strings(format lat,lon or geohash)).");
}
break;
}
}
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(GeoBoundingBoxQueryBuilder filter, Object 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.setCorners(geoBBox.getTopLeft().getLat(), geoBBox.getTopLeft().getLon(), geoBBox.getBottomRight().getLat(), geoBBox.getBottomRight().getLon());
}
private static boolean isType(Object[] array, Class clazz) {
for (Object o : array) {
if (!clazz.isInstance(o)) {
return false;
}
}
return true;
}
private void twoParameterBBox(GeoBoundingBoxQueryBuilder filter, Object[] values) {
Assert.isTrue(isType(values, GeoPoint.class) || isType(values, String.class), " both elements of boundedBy filter must be type of GeoPoint or text(format lat,lon or geohash)");
if (values[0] instanceof GeoPoint) {
GeoPoint topLeft = (GeoPoint) values[0];
GeoPoint bottomRight = (GeoPoint) values[1];
filter.setCorners(topLeft.getLat(), topLeft.getLon(), bottomRight.getLat(), bottomRight.getLon());
} else {
String topLeft = (String) values[0];
String bottomRight = (String) values[1];
filter.setCorners(topLeft, bottomRight);
}
}
private List<QueryBuilder> buildNegationFilter(String fieldName, Iterator<Criteria.CriteriaEntry> it) {
List<QueryBuilder> notFilterList = new LinkedList<>();
while (it.hasNext()) {
Criteria.CriteriaEntry criteriaEntry = it.next();
QueryBuilder notFilter = QueryBuilders.boolQuery().mustNot(processCriteriaEntry(criteriaEntry.getKey(), criteriaEntry.getValue(), fieldName));
notFilterList.add(notFilter);
}
return notFilterList;
}
}
@@ -1,206 +0,0 @@
/*
* Copyright 2013-2017 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 static org.elasticsearch.index.query.Operator.AND;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.springframework.data.elasticsearch.core.query.Criteria.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
import org.elasticsearch.index.query.*;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.util.Assert;
/**
* CriteriaQueryProcessor
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Franck Marchand
* @author Artur Konczak
*/
class CriteriaQueryProcessor {
QueryBuilder createQueryFromCriteria(Criteria criteria) {
if (criteria == null)
return null;
List<QueryBuilder> shouldQueryBuilderList = new LinkedList<>();
List<QueryBuilder> mustNotQueryBuilderList = new LinkedList<>();
List<QueryBuilder> mustQueryBuilderList = new LinkedList<>();
ListIterator<Criteria> chainIterator = criteria.getCriteriaChain().listIterator();
QueryBuilder firstQuery = null;
boolean negateFirstQuery = false;
while (chainIterator.hasNext()) {
Criteria chainedCriteria = chainIterator.next();
QueryBuilder queryFragmentForCriteria = createQueryFragmentForCriteria(chainedCriteria);
if (queryFragmentForCriteria != null) {
if (firstQuery == null) {
firstQuery = queryFragmentForCriteria;
negateFirstQuery = chainedCriteria.isNegating();
continue;
}
if (chainedCriteria.isOr()) {
shouldQueryBuilderList.add(queryFragmentForCriteria);
} else if (chainedCriteria.isNegating()) {
mustNotQueryBuilderList.add(queryFragmentForCriteria);
} else {
mustQueryBuilderList.add(queryFragmentForCriteria);
}
}
}
if (firstQuery != null) {
if (!shouldQueryBuilderList.isEmpty() && mustNotQueryBuilderList.isEmpty() && mustQueryBuilderList.isEmpty()) {
shouldQueryBuilderList.add(0, firstQuery);
} else {
if (negateFirstQuery) {
mustNotQueryBuilderList.add(0, firstQuery);
} else {
mustQueryBuilderList.add(0, firstQuery);
}
}
}
BoolQueryBuilder query = null;
if (!shouldQueryBuilderList.isEmpty() || !mustNotQueryBuilderList.isEmpty() || !mustQueryBuilderList.isEmpty()) {
query = boolQuery();
for (QueryBuilder qb : shouldQueryBuilderList) {
query.should(qb);
}
for (QueryBuilder qb : mustNotQueryBuilderList) {
query.mustNot(qb);
}
for (QueryBuilder qb : mustQueryBuilderList) {
query.must(qb);
}
}
return query;
}
private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) {
if (chainedCriteria.getQueryCriteriaEntries().isEmpty())
return null;
Iterator<Criteria.CriteriaEntry> it = chainedCriteria.getQueryCriteriaEntries().iterator();
boolean singeEntryCriteria = (chainedCriteria.getQueryCriteriaEntries().size() == 1);
String fieldName = chainedCriteria.getField().getName();
Assert.notNull(fieldName, "Unknown field");
QueryBuilder query = null;
if (singeEntryCriteria) {
Criteria.CriteriaEntry entry = it.next();
query = processCriteriaEntry(entry, fieldName);
} else {
query = boolQuery();
while (it.hasNext()) {
Criteria.CriteriaEntry entry = it.next();
((BoolQueryBuilder) query).must(processCriteriaEntry(entry, fieldName));
}
}
addBoost(query, chainedCriteria.getBoost());
return query;
}
private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry,/* OperationKey key, Object value,*/ String fieldName) {
Object value = entry.getValue();
if (value == null) {
return null;
}
OperationKey key = entry.getKey();
QueryBuilder query = null;
String searchText = StringUtils.toString(value);
Iterable<Object> collection = null;
switch (key) {
case EQUALS:
query = queryStringQuery(searchText).field(fieldName).defaultOperator(AND);
break;
case CONTAINS:
query = queryStringQuery("*" + searchText + "*").field(fieldName).analyzeWildcard(true);
break;
case STARTS_WITH:
query = queryStringQuery(searchText + "*").field(fieldName).analyzeWildcard(true);
break;
case ENDS_WITH:
query = queryStringQuery("*" + searchText).field(fieldName).analyzeWildcard(true);
break;
case EXPRESSION:
query = queryStringQuery(searchText).field(fieldName);
break;
case LESS_EQUAL:
query = rangeQuery(fieldName).lte(value);
break;
case GREATER_EQUAL:
query = rangeQuery(fieldName).gte(value);
break;
case BETWEEN:
Object[] ranges = (Object[]) value;
query = rangeQuery(fieldName).from(ranges[0]).to(ranges[1]);
break;
case LESS:
query = rangeQuery(fieldName).lt(value);
break;
case GREATER:
query = rangeQuery(fieldName).gt(value);
break;
case FUZZY:
query = fuzzyQuery(fieldName, searchText);
break;
case IN:
query = boolQuery();
collection = (Iterable<Object>) value;
for (Object item : collection) {
((BoolQueryBuilder) query).should(queryStringQuery(item.toString()).field(fieldName));
}
break;
case NOT_IN:
query = boolQuery();
collection = (Iterable<Object>) value;
for (Object item : collection) {
((BoolQueryBuilder) query).mustNot(queryStringQuery(item.toString()).field(fieldName));
}
break;
}
return query;
}
private void addBoost(QueryBuilder query, float boost) {
if (Float.isNaN(boost)) {
return;
}
query.boost(boost);
}
}
@@ -1,67 +0,0 @@
/*
* 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;
import java.io.IOException;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.geo.CustomGeoModule;
import org.springframework.data.geo.*;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* DocumentMapper using jackson
*
* @author Artur Konczak
* @author Petar Tahchiev
*/
public class DefaultEntityMapper implements EntityMapper {
private ObjectMapper objectMapper;
public DefaultEntityMapper() {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.registerModule(new CustomGeoModule());
}
@Override
public String mapToString(Object object) throws IOException {
return objectMapper.writeValueAsString(object);
}
@Override
public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
return objectMapper.readValue(source, clazz);
}
}
@@ -1,187 +0,0 @@
/*
* Copyright 2014-2017 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 java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.ScriptedField;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
/**
* @author Artur Konczak
* @author Petar Tahchiev
* @author Young Gu
* @author Oliver Gierke
* @author Mark Paluch
*/
public class DefaultResultMapper extends AbstractResultMapper {
private MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
public DefaultResultMapper() {
super(new DefaultEntityMapper());
}
public DefaultResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
super(new DefaultEntityMapper());
this.mappingContext = mappingContext;
}
public DefaultResultMapper(EntityMapper entityMapper) {
super(entityMapper);
}
public DefaultResultMapper(
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext,
EntityMapper entityMapper) {
super(entityMapper);
this.mappingContext = mappingContext;
}
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
long totalHits = response.getHits().totalHits();
List<T> results = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
if (hit != null) {
T result = null;
if (StringUtils.isNotBlank(hit.sourceAsString())) {
result = mapEntity(hit.sourceAsString(), clazz);
} else {
result = mapEntity(hit.getFields().values(), clazz);
}
setPersistentEntityId(result, hit.getId(), clazz);
populateScriptFields(result, hit);
results.add(result);
}
}
return new AggregatedPageImpl<T>(results, pageable, totalHits, response.getAggregations(), response.getScrollId());
}
private <T> void populateScriptFields(T result, SearchHit hit) {
if (hit.getFields() != null && !hit.getFields().isEmpty() && result != null) {
for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) {
ScriptedField scriptedField = field.getAnnotation(ScriptedField.class);
if (scriptedField != null) {
String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name();
SearchHitField searchHitField = hit.getFields().get(name);
if (searchHitField != null) {
field.setAccessible(true);
try {
field.set(result, searchHitField.getValue());
} catch (IllegalArgumentException e) {
throw new ElasticsearchException("failed to set scripted field: " + name + " with value: "
+ searchHitField.getValue(), e);
} catch (IllegalAccessException e) {
throw new ElasticsearchException("failed to access scripted field: " + name, e);
}
}
}
}
}
}
private <T> T mapEntity(Collection<SearchHitField> values, Class<T> clazz) {
return mapEntity(buildJSONFromFields(values), clazz);
}
private String buildJSONFromFields(Collection<SearchHitField> values) {
JsonFactory nodeFactory = new JsonFactory();
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
generator.writeStartObject();
for (SearchHitField value : values) {
if (value.getValues().size() > 1) {
generator.writeArrayFieldStart(value.getName());
for (Object val : value.getValues()) {
generator.writeObject(val);
}
generator.writeEndArray();
} else {
generator.writeObjectField(value.getName(), value.getValue());
}
}
generator.writeEndObject();
generator.flush();
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
} catch (IOException e) {
return null;
}
}
@Override
public <T> T mapResult(GetResponse response, Class<T> clazz) {
T result = mapEntity(response.getSourceAsString(), clazz);
if (result != null) {
setPersistentEntityId(result, response.getId(), clazz);
}
return result;
}
@Override
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
LinkedList<T> list = new LinkedList<>();
for (MultiGetItemResponse response : responses.getResponses()) {
if (!response.isFailed() && response.getResponse().isExists()) {
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
setPersistentEntityId(result, response.getResponse().getId(), clazz);
list.add(result);
}
}
return list;
}
private <T> void setPersistentEntityId(T result, String id, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
ElasticsearchPersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(clazz);
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
// Only deal with String because ES generated Ids are strings !
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
persistentEntity.getPropertyAccessor(result).setProperty(idProperty, id);
}
}
}
}
@@ -1,577 +0,0 @@
/*
* Copyright 2013-2016 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.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.common.Nullable;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.util.CloseableIterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* ElasticsearchOperations
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Kevin Leturc
*/
public interface ElasticsearchOperations {
/**
* @return Converter in use
*/
ElasticsearchConverter getElasticsearchConverter();
/**
* @return elasticsearch client
*/
Client getClient();
/**
* Create an index for a class
*
* @param clazz
* @param <T>
*/
<T> boolean createIndex(Class<T> clazz);
/**
* Create an index for given indexName
*
* @param indexName
*/
boolean createIndex(String indexName);
/**
* Create an index for given indexName and Settings
*
* @param indexName
* @param settings
*/
boolean createIndex(String indexName, Object settings);
/**
* Create an index for given class and Settings
*
* @param clazz
* @param settings
*/
<T> boolean createIndex(Class<T> clazz, Object settings);
/**
* Create mapping for a class
*
* @param clazz
* @param <T>
*/
<T> boolean putMapping(Class<T> clazz);
/**
* Create mapping for a given indexName and type
*
* @param indexName
* @param type
* @param mappings
*/
boolean putMapping(String indexName, String type, Object mappings);
/**
* Create mapping for a class
*
* @param clazz
* @param mappings
*/
<T> boolean putMapping(Class<T> clazz, Object mappings);
/**
* Get mapping for a class
*
* @param clazz
* @param <T>
*/
<T> Map getMapping(Class<T> clazz);
/**
* Get mapping for a given indexName and type
*
* @param indexName
* @param type
*/
Map getMapping(String indexName, String type);
/**
* Get settings for a given indexName
*
* @param indexName
*/
Map getSetting(String indexName);
/**
* Get settings for a given class
*
* @param clazz
*/
<T> Map getSetting(Class<T> clazz);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @return the first matching object
*/
<T> T queryForObject(GetQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return the first returned object using custom mapper
*
* @param query
* @param clazz
* @param mapper
* @return the first matching object
*/
<T> T queryForObject(GetQuery query, Class<T> clazz, GetResultMapper mapper);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @return the first matching object
*/
<T> T queryForObject(CriteriaQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @return the first matching object
*/
<T> T queryForObject(StringQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return result as {@link Page}
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(SearchQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return result as {@link Page} using custom mapper
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper);
/**
* Execute the query against elasticsearch and return result as {@link Page}
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(CriteriaQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return result as {@link Page}
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(StringQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return result as {@link Page} using custom mapper
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(StringQuery query, Class<T> clazz, SearchResultMapper mapper);
/**
* Executes the given {@link CriteriaQuery} against elasticsearch and return result as {@link CloseableIterator}.
* <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of error.
*
* @param <T> element return type
* @param query
* @param clazz
* @return
* @since 1.3
*/
<T> CloseableIterator<T> stream(CriteriaQuery query, Class<T> clazz);
/**
* Executes the given {@link SearchQuery} against elasticsearch and return result as {@link CloseableIterator}.
* <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of error.
*
* @param <T> element return type
* @param query
* @param clazz
* @return
* @since 1.3
*/
<T> CloseableIterator<T> stream(SearchQuery query, Class<T> clazz);
/**
* Executes the given {@link SearchQuery} against elasticsearch and return result as {@link CloseableIterator} using custom mapper.
* <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of error.
*
* @param <T> element return type
* @param query
* @param clazz
* @param mapper
* @return
* @since 1.3
*/
<T> CloseableIterator<T> stream(SearchQuery query, Class<T> clazz, SearchResultMapper mapper);
/**
* Execute the criteria query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> List<T> queryForList(CriteriaQuery query, Class<T> clazz);
/**
* Execute the string query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> List<T> queryForList(StringQuery query, Class<T> clazz);
/**
* Execute the search query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> List<T> queryForList(SearchQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return ids
*
* @param query
* @return
*/
<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
*
* @param query
* @param clazz
* @return
*/
<T> long count(SearchQuery query, Class<T> clazz);
/**
* return number of elements found by given query
*
* @param query
* @return
*/
<T> long count(SearchQuery query);
/**
* Execute a multiGet against elasticsearch for the given ids
*
* @param searchQuery
* @param clazz
* @return
*/
<T> LinkedList<T> multiGet(SearchQuery searchQuery, Class<T> clazz);
/**
* Execute a multiGet against elasticsearch for the given ids with MultiGetResultMapper
*
* @param searchQuery
* @param clazz
* @param multiGetResultMapper
* @return
*/
<T> LinkedList<T> multiGet(SearchQuery searchQuery, Class<T> clazz, MultiGetResultMapper multiGetResultMapper);
/**
* Index an object. Will do save or update
*
* @param query
* @return returns the document id
*/
String index(IndexQuery query);
/**
* Partial update of the document
*
* @param updateQuery
* @return
*/
UpdateResponse update(UpdateQuery updateQuery);
/**
* Bulk index all objects. Will do save or update
*
* @param queries
*/
void bulkIndex(List<IndexQuery> queries);
/**
* Bulk update all objects. Will do update
*
* @param queries
*/
void bulkUpdate(List<UpdateQuery> queries);
/**
* Delete the one object with provided id
*
* @param indexName
* @param type
* @param id
* @return documentId of the document deleted
*/
String delete(String indexName, String type, String id);
/**
* Delete all records matching the criteria
*
* @param clazz
* @param criteriaQuery
*/
<T> void delete(CriteriaQuery criteriaQuery, Class<T> clazz);
/**
* Delete the one object with provided id
*
* @param clazz
* @param id
* @return documentId of the document deleted
*/
<T> String delete(Class<T> clazz, String id);
/**
* Delete all records matching the query
*
* @param clazz
* @param query
*/
<T> void delete(DeleteQuery query, Class<T> clazz);
/**
* Delete all records matching the query
*
* @param query
*/
void delete(DeleteQuery query);
/**
* Deletes an index for given entity
*
* @param clazz
* @param <T>
* @return
*/
<T> boolean deleteIndex(Class<T> clazz);
/**
* Deletes an index for given indexName
*
* @param indexName
* @return
*/
boolean deleteIndex(String indexName);
/**
* check if index is exists
*
* @param clazz
* @param <T>
* @return
*/
<T> boolean indexExists(Class<T> clazz);
/**
* check if index is exists for given IndexName
*
* @param indexName
* @return
*/
boolean indexExists(String indexName);
/**
* check if type is exists in an index
*
* @param index
* @param type
* @return
*/
boolean typeExists(String index, String type);
/**
* refresh the index
*
* @param indexName
*
*/
void refresh(String indexName);
/**
* refresh the index
*
* @param clazz
*
*/
<T> void refresh(Class<T> clazz);
/**
* Returns scrolled page for given query
*
* @param query The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param clazz The class of entity to retrieve.
* @return The scan id for input query.
*/
<T> Page<T> startScroll(long scrollTimeInMillis, SearchQuery query, Class<T> clazz);
/**
* Returns scrolled page for given query
*
* @param query The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param mapper Custom impl to map result to entities
* @return The scan id for input query.
*/
<T> Page<T> startScroll(long scrollTimeInMillis, SearchQuery query, Class<T> clazz, SearchResultMapper mapper);
/**
* Returns scrolled page for given query
*
* @param criteriaQuery The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param clazz The class of entity to retrieve.
* @return The scan id for input query.
*/
<T> Page<T> startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class<T> clazz);
/**
* Returns scrolled page for given query
*
* @param criteriaQuery The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param mapper Custom impl to map result to entities
* @return The scan id for input query.
*/
<T> Page<T> startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class<T> clazz, SearchResultMapper mapper);
<T> Page<T> continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz);
<T> Page<T> continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz, SearchResultMapper mapper);
/**
* Clears the search contexts associated with specified scroll ids.
*
* @param scrollId
*
*/
<T> void clearScroll(String scrollId);
/**
* more like this query to search for documents that are "like" a specific document.
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz);
/**
* adding new alias
*
* @param query
* @return
*/
Boolean addAlias(AliasQuery query);
/**
* removing previously created alias
*
* @param query
* @return
*/
Boolean removeAlias(AliasQuery query);
/**
* get all the alias pointing to specified index
*
* @param indexName
* @return
*/
List<AliasMetaData> queryForAlias(String indexName);
<T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor);
ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz);
}
@@ -1,32 +0,0 @@
/*
* 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;
import java.io.IOException;
/**
* DocumentMapper interface, it will allow to customize how we mapping object to json
*
* @author Artur Konczak
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public interface EntityMapper {
public String mapToString(Object object) throws IOException;
public <T> T mapToObject(String source, Class<T> clazz) throws IOException;
}
@@ -1,37 +0,0 @@
/*
* 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;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.facet.FacetResult;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public interface FacetedPage<T> extends Page<T> {
boolean hasFacets();
List<FacetResult> getFacets();
FacetResult getFacet(String name);
}
@@ -1,165 +0,0 @@
/*
* Copyright 2014-2017 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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.joda.time.DateTime;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.data.elasticsearch.core.facet.FacetResult;
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequest;
import org.springframework.data.elasticsearch.core.facet.result.HistogramResult;
import org.springframework.data.elasticsearch.core.facet.result.IntervalUnit;
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
import org.springframework.data.elasticsearch.core.facet.result.StatisticalResult;
import org.springframework.data.elasticsearch.core.facet.result.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
/**
* Container for query result and facet results
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
* @author Philipp Kräutli
*/
@Deprecated
public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedPage<T>, AggregatedPage<T> {
private List<FacetResult> facets;
private Map<String, FacetResult> mapOfFacets = new HashMap<>();
public FacetedPageImpl(List<T> content) {
super(content);
}
public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, Pageable.unpaged(), total);
}
@Override
public boolean hasFacets() {
processAggregations();
return facets != null && facets.size() > 0;
}
@Override
public List<FacetResult> getFacets() {
processAggregations();
return facets;
}
@Override
public FacetResult getFacet(String name) {
processAggregations();
return mapOfFacets.get(name);
}
private void addFacet(FacetResult facetResult) {
facets.add(facetResult);
mapOfFacets.put(facetResult.getName(), facetResult);
}
/**
* Lazy conversion from aggregation to old facets
*/
private void processAggregations() {
if (facets != null) {
return;
}
facets = new ArrayList<>();
Aggregations aggregations = getAggregations();
if (aggregations == null) {
return;
}
for (Aggregation agg : aggregations) {
processAggregation(agg);
}
}
private void processAggregation(Aggregation agg)
{
if (agg instanceof Terms) {
processTermAggregation((Terms) agg);
}
if (agg instanceof Range) {
processRangeAggregation((Range) agg);
}
if (agg instanceof ExtendedStats) {
processExtendedStatsAggregation((ExtendedStats) agg);
}
if (agg instanceof Histogram) {
processHistogramAggregation((Histogram) agg);
}
}
private void processTermAggregation(Terms agg)
{
List<Term> terms = new ArrayList<>();
for (Terms.Bucket t : agg.getBuckets()) {
terms.add(new Term(t.getKeyAsString(), t.getDocCount()));
}
addFacet(new TermResult(agg.getName(), terms, terms.size(), agg.getSumOfOtherDocCounts(), 0));
}
private void processRangeAggregation(Range agg)
{
List<? extends Range.Bucket> buckets = ((Range) agg).getBuckets();
List<org.springframework.data.elasticsearch.core.facet.result.Range> ranges = new ArrayList<>();
for (Range.Bucket b : buckets) {
ExtendedStats rStats = b.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (rStats != null) {
Sum sum = b.getAggregations().get(RangeFacetRequest.RANGE_INTERNAL_SUM);
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), (Double) b.getTo(), b.getDocCount(), sum != null ? sum.getValue() : rStats.getSum(), rStats.getCount(), rStats.getMin(), rStats.getMax()));
} else {
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), (Double) b.getTo(), b.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new RangeResult(agg.getName(), ranges));
}
private void processExtendedStatsAggregation(ExtendedStats agg)
{
addFacet(new StatisticalResult(agg.getName(), agg.getCount(), agg.getMax(), agg.getMin(), agg.getAvg(), agg.getStdDeviation(), agg.getSumOfSquares(), agg.getSum(), agg.getVariance()));
}
private void processHistogramAggregation(Histogram agg)
{
List<IntervalUnit> intervals = new ArrayList<>();
for (Histogram.Bucket h : agg.getBuckets()) {
ExtendedStats hStats = h.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (hStats != null) {
intervals.add(new IntervalUnit(((DateTime) h.getKey()).getMillis(), h.getDocCount(), h.getDocCount(), hStats.getSum(), hStats.getAvg(), hStats.getMin(), hStats.getMax()));
} else {
intervals.add(new IntervalUnit(((DateTime) h.getKey()).getMillis(), h.getDocCount(), h.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new HistogramResult(agg.getName(), intervals));
}
}
@@ -1,27 +0,0 @@
/*
* 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;
import org.elasticsearch.action.get.GetResponse;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
public interface GetResultMapper {
<T> T mapResult(GetResponse response, Class<T> clazz);
}
@@ -1,362 +0,0 @@
/*
* Copyright 2014-2017 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 java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.completion.Completion;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import static org.apache.commons.lang.StringUtils.*;
import static org.elasticsearch.common.xcontent.XContentFactory.*;
import static org.springframework.util.StringUtils.*;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Kevin Leturc
* @author Alexander Volz
* @author Dennis Maaß
* @author Pavel Luhin
* @author Mark Paluch
*/
class MappingBuilder {
public static final String FIELD_DATA = "fielddata";
public static final String FIELD_STORE = "store";
public static final String FIELD_TYPE = "type";
public static final String FIELD_INDEX = "index";
public static final String FIELD_FORMAT = "format";
public static final String FIELD_SEARCH_ANALYZER = "search_analyzer";
public static final String FIELD_INDEX_ANALYZER = "analyzer";
public static final String FIELD_PROPERTIES = "properties";
public static final String FIELD_PARENT = "_parent";
public static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators";
public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
public static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length";
public static final String INDEX_VALUE_NOT_ANALYZED = "not_analyzed";
public static final String TYPE_VALUE_STRING = "text";
public static final String TYPE_VALUE_GEO_POINT = "geo_point";
public static final String TYPE_VALUE_COMPLETION = "completion";
public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix";
public static final String TYPE_VALUE_GEO_HASH_PRECISION = "geohash_precision";
private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = SimpleTypeHolder.DEFAULT;
static XContentBuilder buildMapping(Class clazz, String indexType, String idFieldName, String parentType) throws IOException {
XContentBuilder mapping = jsonBuilder().startObject().startObject(indexType);
// Parent
if (hasText(parentType)) {
mapping.startObject(FIELD_PARENT).field(FIELD_TYPE, parentType).endObject();
}
// Properties
XContentBuilder xContentBuilder = mapping.startObject(FIELD_PROPERTIES);
mapEntity(xContentBuilder, clazz, true, idFieldName, EMPTY, false, FieldType.Auto, null);
return xContentBuilder.endObject().endObject().endObject();
}
private static void mapEntity(XContentBuilder xContentBuilder, Class clazz, boolean isRootObject, String idFieldName,
String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType, Field fieldAnnotation) throws IOException {
java.lang.reflect.Field[] fields = retrieveFields(clazz);
if (!isRootObject && (isAnyPropertyAnnotatedAsField(fields) || nestedOrObjectField)) {
String type = FieldType.Object.toString().toLowerCase();
if (nestedOrObjectField) {
type = fieldType.toString().toLowerCase();
}
XContentBuilder t = xContentBuilder.startObject(nestedObjectFieldName).field(FIELD_TYPE, type);
if (nestedOrObjectField && FieldType.Nested == fieldType && fieldAnnotation.includeInParent()) {
t.field("include_in_parent", fieldAnnotation.includeInParent());
}
t.startObject(FIELD_PROPERTIES);
}
for (java.lang.reflect.Field field : fields) {
if (field.isAnnotationPresent(Transient.class) || isInIgnoreFields(field, fieldAnnotation)) {
continue;
}
if (field.isAnnotationPresent(Mapping.class)) {
String mappingPath = field.getAnnotation(Mapping.class).mappingPath();
if (isNotBlank(mappingPath)) {
ClassPathResource mappings = new ClassPathResource(mappingPath);
if (mappings.exists()) {
xContentBuilder.rawField(field.getName(), mappings.getInputStream());
continue;
}
}
}
boolean isGeoPointField = isGeoPointField(field);
boolean isCompletionField = isCompletionField(field);
Field singleField = field.getAnnotation(Field.class);
if (!isGeoPointField && !isCompletionField && isEntity(field) && isAnnotated(field)) {
if (singleField == null) {
continue;
}
boolean nestedOrObject = isNestedOrObjectField(field);
mapEntity(xContentBuilder, getFieldType(field), false, EMPTY, field.getName(), nestedOrObject, singleField.type(), field.getAnnotation(Field.class));
if (nestedOrObject) {
continue;
}
}
MultiField multiField = field.getAnnotation(MultiField.class);
if (isGeoPointField) {
applyGeoPointFieldMapping(xContentBuilder, field);
}
if (isCompletionField) {
CompletionField completionField = field.getAnnotation(CompletionField.class);
applyCompletionFieldMapping(xContentBuilder, field, completionField);
}
if (isRootObject && singleField != null && isIdField(field, idFieldName)) {
applyDefaultIdFieldMapping(xContentBuilder, field);
} else if (multiField != null) {
addMultiFieldMapping(xContentBuilder, field, multiField, isNestedOrObjectField(field));
} else if (singleField != null) {
addSingleFieldMapping(xContentBuilder, field, singleField, isNestedOrObjectField(field));
}
}
if (!isRootObject && isAnyPropertyAnnotatedAsField(fields) || nestedOrObjectField) {
xContentBuilder.endObject().endObject();
}
}
private static java.lang.reflect.Field[] retrieveFields(Class clazz) {
// Create list of fields.
List<java.lang.reflect.Field> fields = new ArrayList<>();
// Keep backing up the inheritance hierarchy.
Class targetClass = clazz;
do {
fields.addAll(Arrays.asList(targetClass.getDeclaredFields()));
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return fields.toArray(new java.lang.reflect.Field[fields.size()]);
}
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 ||
field.getAnnotation(CompletionField.class) != null;
}
private static void applyGeoPointFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
xContentBuilder.startObject(field.getName());
xContentBuilder.field(FIELD_TYPE, TYPE_VALUE_GEO_POINT);
xContentBuilder.endObject();
}
private static void applyCompletionFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field, CompletionField annotation) throws IOException {
xContentBuilder.startObject(field.getName());
xContentBuilder.field(FIELD_TYPE, TYPE_VALUE_COMPLETION);
if (annotation != null) {
xContentBuilder.field(COMPLETION_MAX_INPUT_LENGTH, annotation.maxInputLength());
xContentBuilder.field(COMPLETION_PRESERVE_POSITION_INCREMENTS, annotation.preservePositionIncrements());
xContentBuilder.field(COMPLETION_PRESERVE_SEPARATORS, annotation.preserveSeparators());
if (isNotBlank(annotation.searchAnalyzer())) {
xContentBuilder.field(FIELD_SEARCH_ANALYZER, annotation.searchAnalyzer());
}
if (isNotBlank(annotation.analyzer())) {
xContentBuilder.field(FIELD_INDEX_ANALYZER, annotation.analyzer());
}
}
xContentBuilder.endObject();
}
private static void applyDefaultIdFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field)
throws IOException {
xContentBuilder.startObject(field.getName())
.field(FIELD_TYPE, TYPE_VALUE_STRING)
.field(FIELD_INDEX, INDEX_VALUE_NOT_ANALYZED);
xContentBuilder.endObject();
}
/**
* Apply mapping for a single @Field annotation
*
* @throws IOException
*/
private static void addSingleFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field,
Field fieldAnnotation, boolean nestedOrObjectField) throws IOException {
xContentBuilder.startObject(field.getName());
if(!nestedOrObjectField) {
xContentBuilder.field(FIELD_STORE, fieldAnnotation.store());
}
if(fieldAnnotation.fielddata()) {
xContentBuilder.field(FIELD_DATA, fieldAnnotation.fielddata());
}
if (FieldType.Auto != fieldAnnotation.type()) {
xContentBuilder.field(FIELD_TYPE, fieldAnnotation.type().name().toLowerCase());
if (FieldType.Date == fieldAnnotation.type() && DateFormat.none != fieldAnnotation.format()) {
xContentBuilder.field(FIELD_FORMAT, DateFormat.custom == fieldAnnotation.format()
? fieldAnnotation.pattern() : fieldAnnotation.format());
}
}
if(!fieldAnnotation.index()) {
xContentBuilder.field(FIELD_INDEX, fieldAnnotation.index());
}
if (isNotBlank(fieldAnnotation.searchAnalyzer())) {
xContentBuilder.field(FIELD_SEARCH_ANALYZER, fieldAnnotation.searchAnalyzer());
}
if (isNotBlank(fieldAnnotation.analyzer())) {
xContentBuilder.field(FIELD_INDEX_ANALYZER, fieldAnnotation.analyzer());
}
xContentBuilder.endObject();
}
/**
* Apply mapping for a single nested @Field annotation
*
* @throws IOException
*/
private static void addNestedFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
InnerField annotation) throws IOException {
builder.startObject(annotation.suffix());
//builder.field(FIELD_STORE, annotation.store());
if (FieldType.Auto != annotation.type()) {
builder.field(FIELD_TYPE, annotation.type().name().toLowerCase());
}
if(!annotation.index()) {
builder.field(FIELD_INDEX, annotation.index());
}
if (isNotBlank(annotation.searchAnalyzer())) {
builder.field(FIELD_SEARCH_ANALYZER, annotation.searchAnalyzer());
}
if (isNotBlank(annotation.indexAnalyzer())) {
builder.field(FIELD_INDEX_ANALYZER, annotation.indexAnalyzer());
}
if (annotation.fielddata()) {
builder.field(FIELD_DATA, annotation.fielddata());
}
builder.endObject();
}
/**
* Multi field mappings for string type fields, support for sorts and facets
*
* @throws IOException
*/
private static void addMultiFieldMapping(XContentBuilder builder, java.lang.reflect.Field field,
MultiField annotation, boolean nestedOrObjectField) throws IOException {
builder.startObject(field.getName());
builder.field(FIELD_TYPE, annotation.mainField().type());
builder.startObject("fields");
//add standard field
//addSingleFieldMapping(builder, field, annotation.mainField(), nestedOrObjectField);
for (InnerField innerField : annotation.otherFields()) {
addNestedFieldMapping(builder, field, innerField);
}
builder.endObject();
builder.endObject();
}
protected static boolean isEntity(java.lang.reflect.Field field) {
TypeInformation typeInformation = ClassTypeInformation.from(field.getType());
Class<?> clazz = getFieldType(field);
boolean isComplexType = !SIMPLE_TYPE_HOLDER.isSimpleType(clazz);
return isComplexType && !Map.class.isAssignableFrom(typeInformation.getType());
}
protected static Class<?> getFieldType(java.lang.reflect.Field field) {
ResolvableType resolvableType = ResolvableType.forField(field);
if (resolvableType.isArray()) {
return resolvableType.getComponentType().getRawClass();
}
ResolvableType componentType = resolvableType.getGeneric(0);
if (Iterable.class.isAssignableFrom(field.getType())
&& componentType != ResolvableType.NONE) {
return componentType.getRawClass();
}
return resolvableType.getRawClass();
}
private static boolean isAnyPropertyAnnotatedAsField(java.lang.reflect.Field[] fields) {
if (fields != null) {
for (java.lang.reflect.Field field : fields) {
if (field.isAnnotationPresent(Field.class)) {
return true;
}
}
}
return false;
}
private static boolean isIdField(java.lang.reflect.Field field, String idFieldName) {
return idFieldName.equals(field.getName());
}
private static boolean isInIgnoreFields(java.lang.reflect.Field field, Field parentFieldAnnotation) {
if (null != parentFieldAnnotation) {
String[] ignoreFields = parentFieldAnnotation.ignoreFields();
return Arrays.asList(ignoreFields).contains(field.getName());
}
return false;
}
private static boolean isNestedOrObjectField(java.lang.reflect.Field field) {
Field fieldAnnotation = field.getAnnotation(Field.class);
return fieldAnnotation != null && (FieldType.Nested == fieldAnnotation.type() || FieldType.Object == fieldAnnotation.type());
}
private static boolean isGeoPointField(java.lang.reflect.Field field) {
return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
}
private static boolean isCompletionField(java.lang.reflect.Field field) {
return field.getType() == Completion.class;
}
}
@@ -1,29 +0,0 @@
/*
* 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;
import java.util.LinkedList;
import org.elasticsearch.action.get.MultiGetResponse;
/**
* @author Mohsin Husen
*/
public interface MultiGetResultMapper {
<T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz);
}
@@ -1,24 +0,0 @@
/*
* 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);
}
@@ -1,29 +0,0 @@
/*
* 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;
/**
* ResultsMapper
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
*/
public interface ResultsMapper extends SearchResultMapper, GetResultMapper, MultiGetResultMapper {
EntityMapper getEntityMapper();
}
@@ -1,13 +0,0 @@
package org.springframework.data.elasticsearch.core;
import org.springframework.data.domain.Page;
/**
* @author Artur Konczak
*/
public interface ScrolledPage<T> extends Page<T> {
String getScrollId();
}
@@ -1,29 +0,0 @@
/*
* 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;
import org.elasticsearch.action.search.SearchResponse;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
/**
* @author Artur Konczak
* @author Petar Tahchiev
*/
public interface SearchResultMapper {
<T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable);
}
@@ -1,18 +0,0 @@
package org.springframework.data.elasticsearch.core.aggregation;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.elasticsearch.core.FacetedPage;
import org.springframework.data.elasticsearch.core.ScrolledPage;
/**
* @author Petar Tahchiev
*/
public interface AggregatedPage<T> extends FacetedPage<T>, ScrolledPage<T> {
boolean hasAggregations();
Aggregations getAggregations();
Aggregation getAggregation(String name);
}
@@ -1,97 +0,0 @@
/*
* Copyright 2017 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.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.FacetedPageImpl;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
/**
* @author Petar Tahchiev
* @author Artur Konczak
* @author Mohsin Husen
*/
public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements AggregatedPage<T> {
private Aggregations aggregations;
private Map<String, Aggregation> mapOfAggregations = new HashMap<>();
private String scrollId;
public AggregatedPageImpl(List<T> content) {
super(content);
}
public AggregatedPageImpl(List<T> content, String scrollId) {
super(content);
this.scrollId = scrollId;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, pageable, total);
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) {
super(content, pageable, total);
this.scrollId = scrollId;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) {
super(content, pageable, total);
this.aggregations = aggregations;
if (aggregations != null) {
for (Aggregation aggregation : aggregations) {
mapOfAggregations.put(aggregation.getName(), aggregation);
}
}
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations, String scrollId) {
super(content, pageable, total);
this.aggregations = aggregations;
this.scrollId = scrollId;
if (aggregations != null) {
for (Aggregation aggregation : aggregations) {
mapOfAggregations.put(aggregation.getName(), aggregation);
}
}
}
@Override
public boolean hasAggregations() {
return aggregations != null && mapOfAggregations.size() > 0;
}
@Override
public Aggregations getAggregations() {
return aggregations;
}
@Override
public Aggregation getAggregation(String name) {
return aggregations == null ? null : aggregations.get(name);
}
@Override
public String getScrollId() {
return scrollId;
}
}
@@ -1,39 +0,0 @@
package org.springframework.data.elasticsearch.core.completion;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
* Based on the reference doc - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
*
* @author Mewes Kochheim
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class Completion {
private String[] input;
private Integer weight;
private Completion() {
//required by mapper to instantiate object
}
public Completion(String[] input) {
this.input = input;
}
public String[] getInput() {
return input;
}
public void setInput(String[] input) {
this.input = input;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
}
@@ -1,77 +0,0 @@
/*
* 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.convert;
import java.util.Date;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.joda.time.ReadableInstant;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.springframework.core.convert.converter.Converter;
/**
* DateTimeConverters
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public final class DateTimeConverters {
private static DateTimeFormatter formatter = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);
public enum JodaDateTimeConverter implements Converter<ReadableInstant, String> {
INSTANCE;
@Override
public String convert(ReadableInstant source) {
if (source == null) {
return null;
}
return formatter.print(source);
}
}
public enum JodaLocalDateTimeConverter implements Converter<LocalDateTime, String> {
INSTANCE;
@Override
public String convert(LocalDateTime source) {
if (source == null) {
return null;
}
return formatter.print(source.toDateTime(DateTimeZone.UTC));
}
}
public enum JavaDateConverter implements Converter<Date, String> {
INSTANCE;
@Override
public String convert(Date source) {
if (source == null) {
return null;
}
return formatter.print(source.getTime());
}
}
}
@@ -1,45 +0,0 @@
/*
* 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.convert;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
/**
* ElasticsearchConverter
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public interface ElasticsearchConverter {
/**
* Returns the underlying {@link org.springframework.data.mapping.context.MappingContext} used by the converter.
*
* @return never {@literal null}
*/
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> getMappingContext();
/**
* Returns the underlying {@link org.springframework.core.convert.ConversionService} used by the converter.
*
* @return never {@literal null}.
*/
ConversionService getConversionService();
}
@@ -1,70 +0,0 @@
/*
* Copyright 2013-2017 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.convert;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.util.Assert;
/**
* MappingElasticsearchConverter
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public class MappingElasticsearchConverter implements ElasticsearchConverter, ApplicationContextAware {
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
private final GenericConversionService conversionService;
@SuppressWarnings("unused")
private ApplicationContext applicationContext;
public MappingElasticsearchConverter(
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
Assert.notNull(mappingContext, "MappingContext must not be null!");
this.mappingContext = mappingContext;
this.conversionService = new DefaultConversionService();
}
@Override
public MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> getMappingContext() {
return mappingContext;
}
@Override
public ConversionService getConversionService() {
return this.conversionService;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
if (mappingContext instanceof ApplicationContextAware) {
((ApplicationContextAware) mappingContext).setApplicationContext(applicationContext);
}
}
}
@@ -1,50 +0,0 @@
/*
* 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.util.Assert;
/**
* @author Artur Konczak
*/
@Deprecated
public abstract class AbstractFacetRequest implements FacetRequest {
public static final String INTERNAL_STATS = "internal-stats";
private String name;
private boolean applyQueryFilter;
public AbstractFacetRequest(String name) {
Assert.hasText(name, "Facet can't be null or empty !!!");
this.name = name;
}
protected String getName() {
return name;
}
public void setApplyQueryFilter(boolean applyQueryFilter) {
this.applyQueryFilter = applyQueryFilter;
}
@Override
public boolean applyQueryFilter() {
return applyQueryFilter;
}
}
@@ -1,47 +0,0 @@
/*
* 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.util.Assert;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class AbstractFacetResult implements FacetResult {
private final String name;
private final FacetType type;
protected AbstractFacetResult(String name, FacetType type) {
Assert.hasText(name, "Facet name can't be null and should have a value");
this.name = name;
this.type = type;
}
@Override
public String getName() {
return name;
}
@Override
public FacetType getType() {
return type;
}
}
@@ -1,33 +0,0 @@
/*
* 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.elasticsearch.search.aggregations.AbstractAggregationBuilder;
/**
* @author Artur Koczak
*/
@Deprecated
public interface FacetRequest {
public static final String FIELD_UNTOUCHED = "untouched";
public static final String FIELD_SORT = "sort";
AbstractAggregationBuilder getFacet();
boolean applyQueryFilter();
}
@@ -1,32 +0,0 @@
/*
* 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;
/**
* Generic interface for all facets
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public interface FacetResult {
String getName();
FacetType getType();
}
@@ -1,27 +0,0 @@
/*
* 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;
/**
* @author Artur Konczak
* @author Petar Tahchiev
*/
@Deprecated
public enum FacetType {
term, range, histogram, statistical
}
@@ -1,73 +0,0 @@
/*
* 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.request;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public class HistogramFacetRequest extends AbstractFacetRequest {
private String field;
private long interval;
private DateHistogramInterval timeUnit;
public HistogramFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setInterval(long interval) {
this.interval = interval;
}
public void setTimeUnit(DateHistogramInterval timeUnit) {
this.timeUnit = timeUnit;
}
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
Assert.isTrue(StringUtils.isNotBlank(field), "Please select field on which to build the facet !!!");
Assert.isTrue(interval > 0, "Please provide interval as positive value greater them zero !!!");
DateHistogramAggregationBuilder dateHistogramBuilder = AggregationBuilders.dateHistogram(getName());
dateHistogramBuilder.field(field);
if (timeUnit != null) {
dateHistogramBuilder.dateHistogramInterval(timeUnit);
} else {
dateHistogramBuilder.interval(interval);
}
dateHistogramBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field));
return dateHistogramBuilder;
}
}
@@ -1,58 +0,0 @@
/*
* 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.request;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Artur Konczak
*/
@Deprecated
public class HistogramFacetRequestBuilder {
HistogramFacetRequest result;
public HistogramFacetRequestBuilder(String name) {
result = new HistogramFacetRequest(name);
}
public HistogramFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public HistogramFacetRequestBuilder interval(long interval) {
result.setInterval(interval);
return this;
}
public HistogramFacetRequestBuilder timeUnit(DateHistogramInterval timeUnit) {
result.setTimeUnit(timeUnit);
return this;
}
public FacetRequest build() {
return result;
}
public HistogramFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
}
@@ -1,43 +0,0 @@
/*
* 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.request;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public class NativeFacetRequest implements FacetRequest {
public NativeFacetRequest() {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
@Override
public AbstractAggregationBuilder getFacet() {
return null;
}
@Override
public boolean applyQueryFilter() {
return false;
}
}
@@ -1,133 +0,0 @@
/*
* Copyright 2014-2017 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.request;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
/**
* Range facet for numeric fields
*
* @author Artur Konczak
* @author Akos Bordas
*/
@Deprecated
public class RangeFacetRequest extends AbstractFacetRequest {
public static final String RANGE_INTERNAL_SUM = "range-internal-sum";
private String field;
private String keyField;
private String valueField;
private List<Entry> entries = new ArrayList<>();
public RangeFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setFields(String keyField, String valueField) {
this.keyField = keyField;
this.valueField = valueField;
}
public void range(Double from, Double to) {
entries.add(new DoubleEntry(from, to));
}
public void range(String from, String to) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
public void addRange(Double from, Double to) {
entries.add(new DoubleEntry(from, to));
}
public void addRange(String from, String to) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
@Override
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
RangeAggregationBuilder rangeBuilder = AggregationBuilders.range(getName());
final String field = StringUtils.isNotBlank(keyField) ? keyField : this.field;
rangeBuilder.field(field);
for (Entry entry : entries) {
DoubleEntry doubleEntry = (DoubleEntry) entry;
rangeBuilder.addRange(validateValue(doubleEntry.getFrom(), Double.NEGATIVE_INFINITY), validateValue(doubleEntry.getTo(), Double.POSITIVE_INFINITY));
}
rangeBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field));
if(StringUtils.isNotBlank(valueField)){
rangeBuilder.subAggregation(AggregationBuilders.sum(RANGE_INTERNAL_SUM).field(valueField));
}
return rangeBuilder;
}
private double validateValue(Double value, double defaultValue) {
return value == null ? defaultValue : value;
}
static class DoubleEntry extends Entry<Double> {
DoubleEntry(Double from, Double to) {
super(from, to);
}
}
static class StringEntry extends Entry<String> {
StringEntry(String from, String to) {
super(from, to);
}
}
static class Entry<T> {
T from;
T to;
Entry(T from, T to) {
this.from = from;
this.to = to;
}
public T getFrom() {
return from;
}
public T getTo() {
return to;
}
}
}
@@ -1,85 +0,0 @@
/*
* 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.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* Basic range facet
*
* @author Artur Konczak
*/
@Deprecated
public class RangeFacetRequestBuilder {
RangeFacetRequest result;
public RangeFacetRequestBuilder(String name) {
result = new RangeFacetRequest(name);
}
public RangeFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public RangeFacetRequestBuilder fields(String keyField, String valueField) {
result.setFields(keyField, valueField);
return this;
}
public RangeFacetRequestBuilder range(double from, double to) {
result.range(from, to);
return this;
}
public RangeFacetRequestBuilder range(String from, String to) {
result.range(from, to);
return this;
}
public RangeFacetRequestBuilder from(double from) {
result.range(from, null);
return this;
}
public RangeFacetRequestBuilder to(double to) {
result.range(null, to);
return this;
}
public RangeFacetRequestBuilder from(String from) {
result.range(from, null);
return this;
}
public RangeFacetRequestBuilder to(String to) {
result.range(null, to);
return this;
}
public RangeFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}
@@ -1,53 +0,0 @@
/*
* 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.request;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalFacetRequest extends AbstractFacetRequest {
private String field;
private String[] fields;
public StatisticalFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setFields(String... fields) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
Assert.isTrue(StringUtils.isNotBlank(field) && fields == null, "Please select field or fields on which to build the facets !!!");
return AggregationBuilders.extendedStats(getName()).field(field);
}
}
@@ -1,52 +0,0 @@
/*
* 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.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalFacetRequestBuilder {
StatisticalFacetRequest result;
public StatisticalFacetRequestBuilder(String name) {
result = new StatisticalFacetRequest(name);
}
public StatisticalFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public StatisticalFacetRequestBuilder fields(String... fields) {
result.setFields(fields);
return this;
}
public StatisticalFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}
@@ -1,27 +0,0 @@
/*
* 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.request;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public enum TermFacetOrder {
ascTerm, descTerm, ascCount, descCount;
}
@@ -1,109 +0,0 @@
/*
* 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.request;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.util.automaton.RegExp;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.support.IncludeExclude;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
/**
* Term facet
*
* @author Artur Konczak
*/
@Deprecated
public class TermFacetRequest extends AbstractFacetRequest {
private String[] fields;
private String[] excludeTerms;
private int size = 10;
private TermFacetOrder order = TermFacetOrder.descCount;
private boolean allTerms = false;
private String regex = null;
public TermFacetRequest(String name) {
super(name);
}
public void setFields(String... fields) {
Assert.isTrue(ArrayUtils.isNotEmpty(fields), "Term agg need one field only");
Assert.isTrue(ArrayUtils.getLength(fields) == 1, "Term agg need one field only");
this.fields = fields;
}
public void setSize(int size) {
Assert.isTrue(size >= 0, "Size should be bigger then zero !!!");
this.size = size;
}
public void setOrder(TermFacetOrder order) {
this.order = order;
}
public void setExcludeTerms(String... excludeTerms) {
this.excludeTerms = excludeTerms;
}
public void setAllTerms(boolean allTerms) {
this.allTerms = allTerms;
}
public void setRegex(String regex) {
this.regex = regex;
}
@Override
public AbstractAggregationBuilder getFacet() {
Assert.notEmpty(fields, "Please select at last one field !!!");
final TermsAggregationBuilder termsBuilder = AggregationBuilders.terms(getName()).field(fields[0]).size(this.size);
switch (order) {
case descTerm:
termsBuilder.order(Terms.Order.term(false));
break;
case ascTerm:
termsBuilder.order(Terms.Order.term(true));
break;
case descCount:
termsBuilder.order(Terms.Order.count(false));
break;
default:
termsBuilder.order(Terms.Order.count(true));
}
if (ArrayUtils.isNotEmpty(excludeTerms)) {
termsBuilder.includeExclude(new IncludeExclude(null,excludeTerms));
}
if (allTerms) {
termsBuilder.size(Integer.MAX_VALUE);
}
if (StringUtils.isNotBlank(regex)) {
termsBuilder.includeExclude(new IncludeExclude(new RegExp(regex),null));
}
return termsBuilder;
}
}
@@ -1,88 +0,0 @@
/*
* 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.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* Basic term facet
*
* @author Artur Konczak
*/
@Deprecated
public class TermFacetRequestBuilder {
private TermFacetRequest result;
public TermFacetRequestBuilder(String name) {
result = new TermFacetRequest(name);
}
public TermFacetRequestBuilder fields(String... fields) {
result.setFields(fields);
return this;
}
public TermFacetRequestBuilder size(int size) {
result.setSize(size);
return this;
}
public TermFacetRequestBuilder excludeTerms(String... terms) {
result.setExcludeTerms(terms);
return this;
}
public TermFacetRequestBuilder allTerms() {
result.setAllTerms(true);
return this;
}
public TermFacetRequestBuilder regex(String regex) {
result.setRegex(regex);
return this;
}
public TermFacetRequestBuilder ascTerm() {
result.setOrder(TermFacetOrder.ascTerm);
return this;
}
public TermFacetRequestBuilder descTerm() {
result.setOrder(TermFacetOrder.descTerm);
return this;
}
public TermFacetRequestBuilder ascCount() {
result.setOrder(TermFacetOrder.ascCount);
return this;
}
public TermFacetRequestBuilder descCount() {
result.setOrder(TermFacetOrder.descCount);
return this;
}
public TermFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}
@@ -1,39 +0,0 @@
/*
* 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.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* @author Artur Konczak
*/
@Deprecated
public class HistogramResult extends AbstractFacetResult {
private List<IntervalUnit> terms;
public HistogramResult(String name, List<IntervalUnit> terms) {
super(name, FacetType.term);
this.terms = terms;
}
public List<IntervalUnit> getIntervalUnit() {
return terms;
}
}
@@ -1,92 +0,0 @@
/*
* 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.result;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Single term
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class IntervalUnit {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long key;
long count;
long totalCount;
double total;
double mean;
double min;
double max;
public IntervalUnit(long key, long count, long totalCount, double total, double mean, double min, double max) {
this.key = key;
this.count = count;
this.totalCount = totalCount;
this.total = total;
this.mean = mean;
this.min = min;
this.max = max;
}
public long getKey() {
return key;
}
public long getCount() {
return count;
}
public long getTotalCount() {
return totalCount;
}
public double getTotal() {
return total;
}
public double getMean() {
return mean;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
@Override
public String toString() {
return "IntervalUnit{" +
"key=" + format.format(new Date(key)) +
", count=" + count +
", totalCount=" + totalCount +
", total=" + total +
", mean=" + mean +
", min=" + min +
", max=" + max +
'}';
}
}
@@ -1,79 +0,0 @@
/*
* 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.result;
/**
* Single range
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class Range {
private Double from;
private Double to;
private long count;
private double total;
private double totalCount;
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
public Range(Double from, Double to, long count, double total, double totalCount, double min, double max) {
this.from = from;
this.to = to;
this.count = count;
this.total = total;
this.totalCount = totalCount;
this.min = min;
this.max = max;
}
public Double getFrom() {
return from;
}
public Double getTo() {
return to;
}
/**
* Return number of documents in range
*
* @return
*/
public long getCount() {
return count;
}
public double getTotal() {
return total;
}
public double getTotalCount() {
return totalCount;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
}
@@ -1,44 +0,0 @@
/*
* 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.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* Basic term facet result
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class RangeResult extends AbstractFacetResult {
private List<Range> ranges;
public RangeResult(String name, List<Range> ranges) {
super(name, FacetType.range);
this.ranges = ranges;
}
public List<Range> getRanges() {
return ranges;
}
}
@@ -1,86 +0,0 @@
/*
* 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.result;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalResult extends AbstractFacetResult {
private long count;
private double max;
private double min;
private double mean;
private double stdDeviation;
private double sumOfSquares;
private double total;
private double variance;
public StatisticalResult(String name, long count, double max, double min, double mean, double stdDeviation, double sumOfSquares, double total, double variance) {
super(name, FacetType.statistical);
this.count = count;
this.max = max;
this.min = min;
this.mean = mean;
this.stdDeviation = stdDeviation;
this.sumOfSquares = sumOfSquares;
this.total = total;
this.variance = variance;
}
public long getCount() {
return count;
}
public double getMax() {
return max;
}
public double getMin() {
return min;
}
public double getMean() {
return mean;
}
public double getStdDeviation() {
return stdDeviation;
}
public double getSumOfSquares() {
return sumOfSquares;
}
public double getTotal() {
return total;
}
public double getVariance() {
return variance;
}
}
@@ -1,44 +0,0 @@
/*
* 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.result;
/**
* Single term
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class Term {
private String term;
private long count;
public Term(String term, long count) {
this.term = term;
this.count = count;
}
public String getTerm() {
return term;
}
public long getCount() {
return count;
}
}
@@ -1,63 +0,0 @@
/*
* 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.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* Basic term facet result
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
* @author Matija Obreza
*/
@Deprecated
public class TermResult extends AbstractFacetResult {
private List<Term> terms;
private long total;
private long other;
private long missing;
public TermResult(String name, List<Term> terms, long total, long other, long missing) {
super(name, FacetType.term);
this.terms = terms;
this.total = total;
this.other = other;
this.missing = missing;
}
public List<Term> getTerms() {
return terms;
}
public long getTotal() {
return total;
}
public long getOther() {
return other;
}
public long getMissing() {
return missing;
}
}
@@ -1,44 +0,0 @@
package org.springframework.data.elasticsearch.core.geo;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.data.geo.Point;
/**
* @author Artur Konaczak
*/
public class CustomGeoModule extends SimpleModule {
private static final long serialVersionUID = 1L;
/**
* Creates a new {@link org.springframework.data.elasticsearch.core.geo.CustomGeoModule} registering serializers and deserializers for spring data commons geo-spatial types.
*/
public CustomGeoModule() {
super("Spring Data Elasticsearch Geo", new Version(1, 0, 0, null, "org.springframework.data.elasticsearch", "spring-data-elasticsearch-geo"));
addSerializer(Point.class, new PointSerializer());
addDeserializer(Point.class, new PointDeserializer());
}
}
class PointSerializer extends JsonSerializer<Point> {
@Override
public void serialize(Point value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeObject(GeoPoint.fromPoint(value));
}
}
class PointDeserializer extends JsonDeserializer<Point> {
@Override
public Point deserialize(JsonParser p, DeserializationContext context) throws IOException {
return GeoPoint.toPoint(p.readValueAs(GeoPoint.class));
}
}
@@ -1,56 +0,0 @@
/*
* 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.geo;
import org.springframework.data.geo.Box;
/**
* Geo bbox used for #{@link org.springframework.data.elasticsearch.core.query.Criteria}.
*
* @author Franck Marchand
*/
public class GeoBox {
private GeoPoint topLeft;
private GeoPoint bottomRight;
public GeoBox(GeoPoint topLeft, GeoPoint bottomRight) {
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
public GeoPoint getTopLeft() {
return topLeft;
}
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);
}
}
@@ -1,63 +0,0 @@
/*
* Copyright 2013-2016 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.geo;
import org.springframework.data.geo.Point;
/**
* geo-location used for #{@link org.springframework.data.elasticsearch.core.query.Criteria}.
*
* @author Franck Marchand
* @author Mohsin Husen
*/
public class GeoPoint {
private double lat;
private double lon;
private GeoPoint() {
//required by mapper to instantiate object
}
public GeoPoint(double latitude, double longitude) {
this.lat = latitude;
this.lon = longitude;
}
public double getLat() {
return lat;
}
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.getX(), point.getY());
}
public static Point toPoint(GeoPoint point) {
return new Point(point.getLat(), point.getLon());
}
}
@@ -1,52 +0,0 @@
/*
* Copyright 2013-2017 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.mapping;
import org.springframework.data.mapping.PersistentEntity;
/**
* ElasticsearchPersistentEntity
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> {
String getIndexName();
String getIndexType();
short getShards();
short getReplicas();
boolean isUseServerConfiguration();
String getRefreshInterval();
String getIndexStoreType();
ElasticsearchPersistentProperty getVersionProperty();
String getParentType();
ElasticsearchPersistentProperty getParentIdProperty();
String settingPath();
boolean isCreateIndexAndMapping();
}
@@ -1,40 +0,0 @@
/*
* 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.mapping;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mapping.PersistentProperty;
/**
* ElasticsearchPersistentProperty
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public interface ElasticsearchPersistentProperty extends PersistentProperty<ElasticsearchPersistentProperty> {
String getFieldName();
public enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> {
INSTANCE;
public String convert(ElasticsearchPersistentProperty source) {
return source.getFieldName();
}
}
}
@@ -1,58 +0,0 @@
/*
* Copyright 2013-2017 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.mapping;
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.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
/**
* SimpleElasticsearchMappingContext
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public class SimpleElasticsearchMappingContext extends
AbstractMappingContext<SimpleElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> implements ApplicationContextAware {
private ApplicationContext context;
@Override
protected <T> SimpleElasticsearchPersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
final SimpleElasticsearchPersistentEntity<T> persistentEntity = new SimpleElasticsearchPersistentEntity<>(
typeInformation);
if (context != null) {
persistentEntity.setApplicationContext(context);
}
return persistentEntity;
}
@Override
protected ElasticsearchPersistentProperty createPersistentProperty(Property property,
SimpleElasticsearchPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
return new SimpleElasticsearchPersistentProperty(property, owner, simpleTypeHolder);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
}
@@ -1,171 +0,0 @@
/*
* Copyright 2013-2017 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.mapping;
import static org.springframework.util.StringUtils.*;
import java.util.Locale;
import java.util.Optional;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.data.elasticsearch.annotations.Document;
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;
/**
* Elasticsearch specific {@link org.springframework.data.mapping.PersistentEntity} implementation holding
*
* @param <T>
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntity<T, ElasticsearchPersistentProperty>
implements ElasticsearchPersistentEntity<T>, ApplicationContextAware {
private final StandardEvaluationContext context;
private final SpelExpressionParser parser;
private String indexName;
private String indexType;
private boolean useServerConfiguration;
private short shards;
private short replicas;
private String refreshInterval;
private String indexStoreType;
private String parentType;
private ElasticsearchPersistentProperty parentIdProperty;
private String settingPath;
private boolean createIndexAndMapping;
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);
Assert.hasText(document.indexName(),
" Unknown indexName. Make sure the indexName is defined. e.g @Document(indexName=\"foo\")");
this.indexName = document.indexName();
this.indexType = hasText(document.type()) ? document.type() : clazz.getSimpleName().toLowerCase(Locale.ENGLISH);
this.useServerConfiguration = document.useServerConfiguration();
this.shards = document.shards();
this.replicas = document.replicas();
this.refreshInterval = document.refreshInterval();
this.indexStoreType = document.indexStoreType();
this.createIndexAndMapping = document.createIndex();
}
if (clazz.isAnnotationPresent(Setting.class)) {
this.settingPath = typeInformation.getType().getAnnotation(Setting.class).settingPath();
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context.addPropertyAccessor(new BeanFactoryAccessor());
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
context.setRootObject(applicationContext);
}
@Override
public String getIndexName() {
Expression expression = parser.parseExpression(indexName, ParserContext.TEMPLATE_EXPRESSION);
return expression.getValue(context, String.class);
}
@Override
public String getIndexType() {
Expression expression = parser.parseExpression(indexType, ParserContext.TEMPLATE_EXPRESSION);
return expression.getValue(context, String.class);
}
@Override
public String getIndexStoreType() {
return indexStoreType;
}
@Override
public short getShards() {
return shards;
}
@Override
public short getReplicas() {
return replicas;
}
@Override
public boolean isUseServerConfiguration() {
return useServerConfiguration;
}
@Override
public String getRefreshInterval() {
return refreshInterval;
}
@Override
public String getParentType() {
return parentType;
}
@Override
public ElasticsearchPersistentProperty getParentIdProperty() {
return parentIdProperty;
}
@Override
public String settingPath() {
return settingPath;
}
@Override
public boolean isCreateIndexAndMapping() {
return createIndexAndMapping;
}
@Override
public void addPersistentProperty(ElasticsearchPersistentProperty property) {
super.addPersistentProperty(property);
Parent annotation = property.findAnnotation(Parent.class);
if (annotation != null) {
Assert.isNull(this.parentIdProperty, "Only one field can hold a @Parent annotation");
Assert.isNull(this.parentType, "Only one field can hold a @Parent annotation");
Assert.isTrue(property.getType() == String.class, "Parent ID property should be String");
this.parentIdProperty = property;
this.parentType = annotation.type();
}
if (property.isVersionProperty()) {
Assert.isTrue(property.getType() == Long.class, "Version property should be Long");
}
}
}
@@ -1,65 +0,0 @@
/*
* Copyright 2013-2017 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.mapping;
import java.util.HashSet;
import java.util.Set;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder;
/**
* Elasticsearch specific {@link org.springframework.data.mapping.PersistentProperty} implementation processing
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public class SimpleElasticsearchPersistentProperty extends
AnnotationBasedPersistentProperty<ElasticsearchPersistentProperty> implements ElasticsearchPersistentProperty {
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<>();
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<>();
static {
SUPPORTED_ID_TYPES.add(String.class);
SUPPORTED_ID_PROPERTY_NAMES.add("id");
SUPPORTED_ID_PROPERTY_NAMES.add("documentId");
}
public SimpleElasticsearchPersistentProperty(Property property,
PersistentEntity<?, ElasticsearchPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
super(property, owner, simpleTypeHolder);
}
@Override
public String getFieldName() {
return getProperty().getName();
}
@Override
public boolean isIdProperty() {
return super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName());
}
@Override
protected Association<ElasticsearchPersistentProperty> createAssociation() {
return null;
}
}
@@ -1,152 +0,0 @@
/*
* Copyright 2013-2017 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.query;
import static java.util.Collections.addAll;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.elasticsearch.action.search.SearchType;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.Assert;
/**
* AbstractQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
abstract class AbstractQuery implements Query {
protected Pageable pageable = DEFAULT_PAGE;
protected Sort sort;
protected List<String> indices = new ArrayList<>();
protected List<String> types = new ArrayList<>();
protected List<String> fields = new ArrayList<>();
protected SourceFilter sourceFilter;
protected float minScore;
protected Collection<String> ids;
protected String route;
protected SearchType searchType = SearchType.DFS_QUERY_THEN_FETCH;
@Override
public Sort getSort() {
return this.sort;
}
@Override
public Pageable getPageable() {
return this.pageable;
}
@Override
public final <T extends Query> T setPageable(Pageable pageable) {
Assert.notNull(pageable, "Pageable must not be null!");
this.pageable = pageable;
return (T) this.addSort(pageable.getSort());
}
@Override
public void addFields(String... fields) {
addAll(this.fields, fields);
}
@Override
public List<String> getFields() {
return fields;
}
@Override
public List<String> getIndices() {
return indices;
}
@Override
public void addIndices(String... indices) {
addAll(this.indices, indices);
}
@Override
public void addTypes(String... types) {
addAll(this.types, types);
}
@Override
public List<String> getTypes() {
return types;
}
@Override
public void addSourceFilter(SourceFilter sourceFilter) {
this.sourceFilter = sourceFilter;
}
@Override
public SourceFilter getSourceFilter() {
return sourceFilter;
}
@SuppressWarnings("unchecked")
public final <T extends Query> T addSort(Sort sort) {
if (sort == null) {
return (T) this;
}
if (this.sort == null) {
this.sort = sort;
} else {
this.sort = this.sort.and(sort);
}
return (T) this;
}
public float getMinScore() {
return minScore;
}
public void setMinScore(float minScore) {
this.minScore = minScore;
}
public Collection<String> getIds() {
return ids;
}
public void setIds(Collection<String> ids) {
this.ids = ids;
}
public String getRoute() {
return route;
}
public void setRoute(String route) {
this.route = route;
}
public void setSearchType(SearchType searchType) {
this.searchType = searchType;
}
public SearchType getSearchType() {
return searchType;
}
}
@@ -1,81 +0,0 @@
/*
* 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.query;
import java.util.Map;
import org.elasticsearch.index.query.QueryBuilder;
/**
* @author Mohsin Husen
*/
public class AliasBuilder {
private String indexName;
private String aliasName;
private QueryBuilder filterBuilder;
private Map<String, Object> filter;
private String searchRouting;
private String indexRouting;
private String routing;
public AliasBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public AliasBuilder withAliasName(String aliasName) {
this.aliasName = aliasName;
return this;
}
public AliasBuilder withFilterBuilder(QueryBuilder filterBuilder) {
this.filterBuilder = filterBuilder;
return this;
}
public AliasBuilder withFilter(Map<String, Object> filter) {
this.filter = filter;
return this;
}
public AliasBuilder withSearchRouting(String searchRouting) {
this.searchRouting = searchRouting;
return this;
}
public AliasBuilder withIndexRouting(String indexRouting) {
this.indexRouting = indexRouting;
return this;
}
public AliasBuilder withRouting(String routing) {
this.routing = routing;
return this;
}
public AliasQuery build() {
AliasQuery aliasQuery = new AliasQuery();
aliasQuery.setIndexName(indexName);
aliasQuery.setAliasName(aliasName);
aliasQuery.setFilterBuilder(filterBuilder);
aliasQuery.setFilter(filter);
aliasQuery.setSearchRouting(searchRouting);
aliasQuery.setIndexRouting(indexRouting);
aliasQuery.setRouting(routing);
return aliasQuery;
}
}
@@ -1,92 +0,0 @@
/*
* 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.query;
import java.util.Map;
import org.elasticsearch.index.query.QueryBuilder;
/**
* AliasQuery is useful for creating new alias or deleting existing ones
*
* @author Mohsin Husen
*/
public class AliasQuery {
private String indexName;
private String aliasName;
private QueryBuilder filterBuilder;
private Map<String, Object> filter;
private String searchRouting;
private String indexRouting;
private String routing;
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getAliasName() {
return aliasName;
}
public void setAliasName(String aliasName) {
this.aliasName = aliasName;
}
public QueryBuilder getFilterBuilder() {
return filterBuilder;
}
public void setFilterBuilder(QueryBuilder filterBuilder) {
this.filterBuilder = filterBuilder;
}
public Map<String, Object> getFilter() {
return filter;
}
public void setFilter(Map<String, Object> filter) {
this.filter = filter;
}
public String getSearchRouting() {
return searchRouting;
}
public void setSearchRouting(String searchRouting) {
this.searchRouting = searchRouting;
}
public String getIndexRouting() {
return indexRouting;
}
public void setIndexRouting(String indexRouting) {
this.indexRouting = indexRouting;
}
public String getRouting() {
return routing;
}
public void setRouting(String routing) {
this.routing = routing;
}
}
@@ -1,619 +0,0 @@
/*
* Copyright 2013-2017 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.query;
import java.util.*;
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.Box;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
* Criteria is the central class when constructing queries. It follows more or less a fluent API style, which allows to
* easily chain together multiple criteria.
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Franck Marchand
*/
public class Criteria {
@Override
public String toString() {
return "Criteria{" +
"field=" + field.getName() +
", boost=" + boost +
", negating=" + negating +
", queryCriteria=" + StringUtils.join(queryCriteria, '|') +
", filterCriteria=" + StringUtils.join(filterCriteria, '|') +
'}';
}
public static final String WILDCARD = "*";
public static final String CRITERIA_VALUE_SEPERATOR = " ";
private static final String OR_OPERATOR = " OR ";
private static final String AND_OPERATOR = " AND ";
private Field field;
private float boost = Float.NaN;
private boolean negating = false;
private List<Criteria> criteriaChain = new ArrayList<>(1);
private Set<CriteriaEntry> queryCriteria = new LinkedHashSet<>();
private Set<CriteriaEntry> filterCriteria = new LinkedHashSet<>();
public Criteria() {
}
/**
* Creates a new Criteria with provided field name
*
* @param fieldname
*/
public Criteria(String fieldname) {
this(new SimpleField(fieldname));
}
/**
* Creates a new Criteria for the given field
*
* @param field
*/
public Criteria(Field field) {
Assert.notNull(field, "Field for criteria must not be null");
Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty");
this.criteriaChain.add(this);
this.field = field;
}
protected Criteria(List<Criteria> criteriaChain, String fieldname) {
this(criteriaChain, new SimpleField(fieldname));
}
protected Criteria(List<Criteria> criteriaChain, Field field) {
Assert.notNull(criteriaChain, "CriteriaChain must not be null");
Assert.notNull(field, "Field for criteria must not be null");
Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty");
this.criteriaChain.addAll(criteriaChain);
this.criteriaChain.add(this);
this.field = field;
}
/**
* Static factory method to create a new Criteria for field with given name
*
* @param field
* @return
*/
public static Criteria where(String field) {
return where(new SimpleField(field));
}
/**
* Static factory method to create a new Criteria for provided field
*
* @param field
* @return
*/
public static Criteria where(Field field) {
return new Criteria(field);
}
/**
* Chain using {@code AND}
*
* @param field
* @return
*/
public Criteria and(Field field) {
return new Criteria(this.criteriaChain, field);
}
/**
* Chain using {@code AND}
*
* @param fieldName
* @return
*/
public Criteria and(String fieldName) {
return new Criteria(this.criteriaChain, fieldName);
}
/**
* Chain using {@code AND}
*
* @param criteria
* @return
*/
public Criteria and(Criteria criteria) {
this.criteriaChain.add(criteria);
return this;
}
/**
* Chain using {@code AND}
*
* @param criterias
* @return
*/
public Criteria and(Criteria... criterias) {
this.criteriaChain.addAll(Arrays.asList(criterias));
return this;
}
/**
* Chain using {@code OR}
*
* @param field
* @return
*/
public Criteria or(Field field) {
return new OrCriteria(this.criteriaChain, field);
}
/**
* Chain using {@code OR}
*
* @param criteria
* @return
*/
public Criteria or(Criteria criteria) {
Assert.notNull(criteria, "Cannot chain 'null' criteria.");
Criteria orConnectedCritiera = new OrCriteria(this.criteriaChain, criteria.getField());
orConnectedCritiera.queryCriteria.addAll(criteria.queryCriteria);
return orConnectedCritiera;
}
/**
* Chain using {@code OR}
*
* @param fieldName
* @return
*/
public Criteria or(String fieldName) {
return or(new SimpleField(fieldName));
}
/**
* Crates new CriteriaEntry without any wildcards
*
* @param o
* @return
*/
public Criteria is(Object o) {
queryCriteria.add(new CriteriaEntry(OperationKey.EQUALS, o));
return this;
}
/**
* Crates new CriteriaEntry with leading and trailing wildcards <br/>
* <strong>NOTE: </strong> mind your schema as leading wildcards may not be supported and/or execution might be slow.
*
* @param s
* @return
*/
public Criteria contains(String s) {
assertNoBlankInWildcardedQuery(s, true, true);
queryCriteria.add(new CriteriaEntry(OperationKey.CONTAINS, s));
return this;
}
/**
* Crates new CriteriaEntry with trailing wildcard
*
* @param s
* @return
*/
public Criteria startsWith(String s) {
assertNoBlankInWildcardedQuery(s, true, false);
queryCriteria.add(new CriteriaEntry(OperationKey.STARTS_WITH, s));
return this;
}
/**
* Crates new CriteriaEntry with leading wildcard <br />
* <strong>NOTE: </strong> mind your schema and execution times as leading wildcards may not be supported.
*
* @param s
* @return
*/
public Criteria endsWith(String s) {
assertNoBlankInWildcardedQuery(s, false, true);
queryCriteria.add(new CriteriaEntry(OperationKey.ENDS_WITH, s));
return this;
}
/**
* Crates new CriteriaEntry with trailing -
*
* @return
*/
public Criteria not() {
this.negating = true;
return this;
}
/**
* Crates new CriteriaEntry with trailing ~
*
* @param s
* @return
*/
public Criteria fuzzy(String s) {
queryCriteria.add(new CriteriaEntry(OperationKey.FUZZY, s));
return this;
}
/**
* Crates new CriteriaEntry allowing native elasticsearch expressions
*
* @param s
* @return
*/
public Criteria expression(String s) {
queryCriteria.add(new CriteriaEntry(OperationKey.EXPRESSION, s));
return this;
}
/**
* Boost positive hit with given factor. eg. ^2.3
*
* @param boost
* @return
*/
public Criteria boost(float boost) {
if (boost < 0) {
throw new InvalidDataAccessApiUsageException("Boost must not be negative.");
}
this.boost = boost;
return this;
}
/**
* Crates new CriteriaEntry for {@code RANGE [lowerBound TO upperBound]}
*
* @param lowerBound
* @param upperBound
* @return
*/
public Criteria between(Object lowerBound, Object upperBound) {
if (lowerBound == null && upperBound == null) {
throw new InvalidDataAccessApiUsageException("Range [* TO *] is not allowed");
}
queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[]{lowerBound, upperBound}));
return this;
}
/**
* Crates new CriteriaEntry for {@code RANGE [* TO upperBound]}
*
* @param upperBound
* @return
*/
public Criteria lessThanEqual(Object upperBound) {
if (upperBound == null) {
throw new InvalidDataAccessApiUsageException("UpperBound can't be null");
}
queryCriteria.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound));
return this;
}
public Criteria lessThan(Object upperBound) {
if (upperBound == null) {
throw new InvalidDataAccessApiUsageException("UpperBound can't be null");
}
queryCriteria.add(new CriteriaEntry(OperationKey.LESS, upperBound));
return this;
}
/**
* Crates new CriteriaEntry for {@code RANGE [lowerBound TO *]}
*
* @param lowerBound
* @return
*/
public Criteria greaterThanEqual(Object lowerBound) {
if (lowerBound == null) {
throw new InvalidDataAccessApiUsageException("LowerBound can't be null");
}
queryCriteria.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound));
return this;
}
public Criteria greaterThan(Object lowerBound) {
if (lowerBound == null) {
throw new InvalidDataAccessApiUsageException("LowerBound can't be null");
}
queryCriteria.add(new CriteriaEntry(OperationKey.GREATER, lowerBound));
return this;
}
/**
* Crates new CriteriaEntry for multiple values {@code (arg0 arg1 arg2 ...)}
*
* @param values
* @return
*/
public Criteria in(Object... values) {
return in(toCollection(values));
}
/**
* Crates new CriteriaEntry for multiple values {@code (arg0 arg1 arg2 ...)}
*
* @param values the collection containing the values to match against
* @return
*/
public Criteria in(Iterable<?> values) {
Assert.notNull(values, "Collection of 'in' values must not be null");
queryCriteria.add(new CriteriaEntry(OperationKey.IN, values));
return this;
}
private List<Object> toCollection(Object... values) {
if (values.length == 0 || (values.length > 1 && values[1] instanceof Collection)) {
throw new InvalidDataAccessApiUsageException("At least one element "
+ (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "")
+ " has to be present.");
}
return Arrays.asList(values);
}
public Criteria notIn(Object... values) {
return notIn(toCollection(values));
}
public Criteria notIn(Iterable<?> values) {
Assert.notNull(values, "Collection of 'NotIn' values must not be null");
queryCriteria.add(new CriteriaEntry(OperationKey.NOT_IN, values));
return this;
}
/**
* Creates new CriteriaEntry for {@code location WITHIN distance}
*
* @param location {@link org.springframework.data.elasticsearch.core.geo.GeoPoint} center coordinates
* @param distance {@link String} radius as a string (e.g. : '100km').
* Distance unit :
* either mi/miles or km can be set
* @return Criteria the chaind criteria with the new 'within' criteria included.
*/
public Criteria within(GeoPoint location, String 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 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}
*
* @param geoLocation {@link String} center point
* supported formats:
* lat on = > "41.2,45.1",
* geohash = > "asd9as0d"
* @param distance {@link String} radius as a string (e.g. : '100km').
* Distance unit :
* either mi/miles or km can be set
* @return
*/
public Criteria within(String geoLocation, String distance) {
Assert.isTrue(StringUtils.isNotBlank(geoLocation), "geoLocation value must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{geoLocation, distance}));
return this;
}
/**
* Creates new CriteriaEntry for {@code location GeoBox bounding box}
*
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner)
* @return Criteria the chaind criteria with the new 'boundingBox' criteria included.
*/
public Criteria boundedBy(GeoBox boundingBox) {
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox}));
return this;
}
/**
* Creates new CriteriaEntry for {@code location Box bounding box}
*
* @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner)
* @return Criteria the chaind criteria with the new 'boundingBox' criteria included.
*/
public Criteria boundedBy(Box boundingBox) {
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox.getFirst(), boundingBox.getSecond()}));
return this;
}
/**
* Creates new CriteriaEntry for bounding box created from points
*
* @param topLeftGeohash left top corner of bounding box as geohash
* @param bottomRightGeohash right bottom corner of bounding box as geohash
* @return Criteria the chaind criteria with the new 'boundedBy' criteria included.
*/
public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) {
Assert.isTrue(StringUtils.isNotBlank(topLeftGeohash), "topLeftGeohash must not be empty");
Assert.isTrue(StringUtils.isNotBlank(bottomRightGeohash), "bottomRightGeohash must not be empty");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftGeohash, bottomRightGeohash}));
return this;
}
/**
* Creates new CriteriaEntry for bounding box created from points
*
* @param topLeftPoint left top corner of bounding box
* @param bottomRightPoint right bottom corner of bounding box
* @return Criteria the chaind criteria with the new 'boundedBy' criteria included.
*/
public Criteria boundedBy(GeoPoint topLeftPoint, GeoPoint bottomRightPoint) {
Assert.notNull(topLeftPoint, "topLeftPoint must not be null");
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftPoint, bottomRightPoint}));
return this;
}
public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) {
Assert.notNull(topLeftPoint, "topLeftPoint must not be null");
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint)}));
return this;
}
private void assertNoBlankInWildcardedQuery(String searchString, boolean leadingWildcard, boolean trailingWildcard) {
if (StringUtils.contains(searchString, CRITERIA_VALUE_SEPERATOR)) {
throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + "\""
+ searchString + "\"" + (trailingWildcard ? "*" : "") + "'. Use expression or multiple clauses instead.");
}
}
/**
* Field targeted by this Criteria
*
* @return
*/
public Field getField() {
return this.field;
}
public Set<CriteriaEntry> getQueryCriteriaEntries() {
return Collections.unmodifiableSet(this.queryCriteria);
}
public Set<CriteriaEntry> getFilterCriteriaEntries() {
return Collections.unmodifiableSet(this.filterCriteria);
}
public Set<CriteriaEntry> getFilterCriteria() {
return filterCriteria;
}
/**
* Conjunction to be used with this criteria (AND | OR)
*
* @return
*/
public String getConjunctionOperator() {
return AND_OPERATOR;
}
public List<Criteria> getCriteriaChain() {
return Collections.unmodifiableList(this.criteriaChain);
}
public boolean isNegating() {
return this.negating;
}
public boolean isAnd() {
return AND_OPERATOR == getConjunctionOperator();
}
public boolean isOr() {
return OR_OPERATOR == getConjunctionOperator();
}
public float getBoost() {
return this.boost;
}
static class OrCriteria extends Criteria {
public OrCriteria() {
super();
}
public OrCriteria(Field field) {
super(field);
}
public OrCriteria(List<Criteria> criteriaChain, Field field) {
super(criteriaChain, field);
}
public OrCriteria(List<Criteria> criteriaChain, String fieldname) {
super(criteriaChain, fieldname);
}
public OrCriteria(String fieldname) {
super(fieldname);
}
@Override
public String getConjunctionOperator() {
return OR_OPERATOR;
}
}
public enum OperationKey {
EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, EXPRESSION, BETWEEN, FUZZY, IN, NOT_IN, WITHIN, BBOX, NEAR, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL;
}
public static class CriteriaEntry {
private OperationKey key;
private Object value;
CriteriaEntry(OperationKey key, Object value) {
this.key = key;
this.value = value;
}
public OperationKey getKey() {
return key;
}
public Object getValue() {
return value;
}
@Override
public String toString() {
return "CriteriaEntry{" +
"key=" + key +
", value=" + value +
'}';
}
}
}
@@ -1,82 +0,0 @@
/*
* Copyright 2013-2017 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.query;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
/**
* CriteriaQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Mark Paluch
*/
public class CriteriaQuery extends AbstractQuery {
private Criteria criteria;
private CriteriaQuery() {}
public CriteriaQuery(Criteria criteria) {
this(criteria, Pageable.unpaged());
}
public CriteriaQuery(Criteria criteria, Pageable pageable) {
Assert.notNull(criteria, "Criteria must not be null!");
Assert.notNull(pageable, "Pageable must not be null!");
this.criteria = criteria;
this.pageable = pageable;
this.addSort(pageable.getSort());
}
public static final Query fromQuery(CriteriaQuery source) {
return fromQuery(source, new CriteriaQuery());
}
public static <T extends CriteriaQuery> T fromQuery(CriteriaQuery source, T destination) {
if (source == null || destination == null) {
return null;
}
if (source.getCriteria() != null) {
destination.addCriteria(source.getCriteria());
}
if (source.getSort() != null) {
destination.addSort(source.getSort());
}
return destination;
}
@SuppressWarnings("unchecked")
public final <T extends CriteriaQuery> T addCriteria(Criteria criteria) {
Assert.notNull(criteria, "Cannot add null criteria.");
if (this.criteria == null) {
this.criteria = criteria;
} else {
this.criteria.and(criteria);
}
return (T) this;
}
public Criteria getCriteria() {
return this.criteria;
}
}
@@ -1,73 +0,0 @@
/*
* Copyright 2013-2016 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.query;
import org.elasticsearch.index.query.QueryBuilder;
/**
* DeleteQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class DeleteQuery {
private QueryBuilder query;
private String index;
private String type;
private Integer pageSize;
private Long scrollTimeInMillis;
public QueryBuilder getQuery() {
return query;
}
public void setQuery(QueryBuilder query) {
this.query = query;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Long getScrollTimeInMillis() {
return scrollTimeInMillis;
}
public void setScrollTimeInMillis(Long scrollTimeInMillis) {
this.scrollTimeInMillis = scrollTimeInMillis;
}
}
@@ -1,42 +0,0 @@
/*
* Copyright 2016 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.query;
/**
* SourceFilter implementation for providing includes and excludes.
*
* @Author Jon Tsiros
*/
public class FetchSourceFilter implements SourceFilter {
private final String[] includes;
private final String[] excludes;
public FetchSourceFilter(final String[] includes, final String[] excludes) {
this.includes = includes;
this.excludes = excludes;
}
@Override
public String[] getIncludes() {
return includes;
}
@Override
public String[] getExcludes() {
return excludes;
}
}
@@ -1,45 +0,0 @@
/*
* Copyright 2016 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.query;
/**
* SourceFilter builder for providing includes and excludes.
*
* @Author Jon Tsiros
*/
public class FetchSourceFilterBuilder {
private String[] includes;
private String[] excludes;
public FetchSourceFilterBuilder withIncludes(String... includes) {
this.includes = includes;
return this;
}
public FetchSourceFilterBuilder withExcludes(String... excludes) {
this.excludes = excludes;
return this;
}
public SourceFilter build() {
if (includes == null) includes = new String[0];
if (excludes == null) excludes = new String[0];
SourceFilter sourceFilter = new FetchSourceFilter(includes, excludes);
return sourceFilter;
}
}
@@ -1,32 +0,0 @@
/*
* 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.query;
/**
* Defines a Field that can be used within a Criteria.
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public interface Field {
/**
* Get the name of the field used in schema.xml of elasticsearch server
*
* @return
*/
String getName();
}
@@ -1,35 +0,0 @@
/*
* 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.query;
/**
* GetQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class GetQuery {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
@@ -1,42 +0,0 @@
/*
* Copyright 2016 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.query;
/**
* Defines a IndexBoost to be applied on the "indices_boost" query clause
*
* @author Thiago Locatelli
*/
public class IndexBoost {
private String indexName;
private float boost;
public IndexBoost(String indexName, float boost) {
this.indexName = indexName;
this.boost = boost;
}
public String getIndexName() {
return indexName;
}
public float getBoost() {
return boost;
}
}
@@ -1,90 +0,0 @@
/*
* 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.query;
/**
* IndexQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class IndexQuery {
private String id;
private Object object;
private Long version;
private String indexName;
private String type;
private String source;
private String parentId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
}
@@ -1,80 +0,0 @@
/*
* 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.query;
/**
* IndexQuery Builder
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class IndexQueryBuilder {
private String id;
private Object object;
private Long version;
private String indexName;
private String type;
private String source;
private String parentId;
public IndexQueryBuilder withId(String id) {
this.id = id;
return this;
}
public IndexQueryBuilder withObject(Object object) {
this.object = object;
return this;
}
public IndexQueryBuilder withVersion(Long version) {
this.version = version;
return this;
}
public IndexQueryBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public IndexQueryBuilder withType(String type) {
this.type = type;
return this;
}
public IndexQueryBuilder withSource(String source) {
this.source = source;
return this;
}
public IndexQueryBuilder withParentId(String parentId) {
this.parentId = parentId;
return this;
}
public IndexQuery build() {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(id);
indexQuery.setIndexName(indexName);
indexQuery.setType(type);
indexQuery.setObject(object);
indexQuery.setParentId(parentId);
indexQuery.setSource(source);
indexQuery.setVersion(version);
return indexQuery;
}
}
@@ -1,187 +0,0 @@
/*
* Copyright 2013-2017 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.query;
import static java.util.Collections.addAll;
import static org.springframework.data.elasticsearch.core.query.AbstractQuery.*;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Pageable;
/**
* MoreLikeThisQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
*/
public class MoreLikeThisQuery {
private String id;
private String indexName;
private String type;
private List<String> searchIndices = new ArrayList<>();
private List<String> searchTypes = new ArrayList<>();
private List<String> fields = new ArrayList<>();
private String routing;
private Float percentTermsToMatch;
private Integer minTermFreq;
private Integer maxQueryTerms;
private List<String> stopWords = new ArrayList<>();
private Integer minDocFreq;
private Integer maxDocFreq;
private Integer minWordLen;
private Integer maxWordLen;
private Float boostTerms;
private Pageable pageable = DEFAULT_PAGE;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<String> getSearchIndices() {
return searchIndices;
}
public void addSearchIndices(String... searchIndices) {
addAll(this.searchIndices, searchIndices);
}
public List<String> getSearchTypes() {
return searchTypes;
}
public void addSearchTypes(String... searchTypes) {
addAll(this.searchTypes, searchTypes);
}
public List<String> getFields() {
return fields;
}
public void addFields(String... fields) {
addAll(this.fields, fields);
}
public String getRouting() {
return routing;
}
public void setRouting(String routing) {
this.routing = routing;
}
public Float getPercentTermsToMatch() {
return percentTermsToMatch;
}
public void setPercentTermsToMatch(Float percentTermsToMatch) {
this.percentTermsToMatch = percentTermsToMatch;
}
public Integer getMinTermFreq() {
return minTermFreq;
}
public void setMinTermFreq(Integer minTermFreq) {
this.minTermFreq = minTermFreq;
}
public Integer getMaxQueryTerms() {
return maxQueryTerms;
}
public void setMaxQueryTerms(Integer maxQueryTerms) {
this.maxQueryTerms = maxQueryTerms;
}
public List<String> getStopWords() {
return stopWords;
}
public void addStopWords(String... stopWords) {
addAll(this.stopWords, stopWords);
}
public Integer getMinDocFreq() {
return minDocFreq;
}
public void setMinDocFreq(Integer minDocFreq) {
this.minDocFreq = minDocFreq;
}
public Integer getMaxDocFreq() {
return maxDocFreq;
}
public void setMaxDocFreq(Integer maxDocFreq) {
this.maxDocFreq = maxDocFreq;
}
public Integer getMinWordLen() {
return minWordLen;
}
public void setMinWordLen(Integer minWordLen) {
this.minWordLen = minWordLen;
}
public Integer getMaxWordLen() {
return maxWordLen;
}
public void setMaxWordLen(Integer maxWordLen) {
this.maxWordLen = maxWordLen;
}
public Float getBoostTerms() {
return boostTerms;
}
public void setBoostTerms(Float boostTerms) {
this.boostTerms = boostTerms;
}
public Pageable getPageable() {
return pageable;
}
public void setPageable(Pageable pageable) {
this.pageable = pageable;
}
}
@@ -1,140 +0,0 @@
/*
* Copyright 2013-2017 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.query;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
import java.util.Arrays;
/**
* NativeSearchQuery
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
*/
public class NativeSearchQuery extends AbstractQuery implements SearchQuery {
private QueryBuilder query;
private QueryBuilder filter;
private List<SortBuilder> sorts;
private final List<ScriptField> scriptFields = new ArrayList<>();
private List<FacetRequest> facets;
private List<AbstractAggregationBuilder> aggregations;
private HighlightBuilder.Field[] highlightFields;
private List<IndexBoost> indicesBoost;
public NativeSearchQuery(QueryBuilder query) {
this.query = query;
}
public NativeSearchQuery(QueryBuilder query, QueryBuilder filter) {
this.query = query;
this.filter = filter;
}
public NativeSearchQuery(QueryBuilder query, QueryBuilder filter, List<SortBuilder> sorts) {
this.query = query;
this.filter = filter;
this.sorts = sorts;
}
public NativeSearchQuery(QueryBuilder query, QueryBuilder filter, List<SortBuilder> sorts, HighlightBuilder.Field[] highlightFields) {
this.query = query;
this.filter = filter;
this.sorts = sorts;
this.highlightFields = highlightFields;
}
public QueryBuilder getQuery() {
return query;
}
public QueryBuilder getFilter() {
return filter;
}
public List<SortBuilder> getElasticsearchSorts() {
return sorts;
}
@Override
public HighlightBuilder.Field[] getHighlightFields() {
return highlightFields;
}
@Override
public List<ScriptField> getScriptFields() { return scriptFields; }
public void setScriptFields(List<ScriptField> scriptFields) {
this.scriptFields.addAll(scriptFields);
}
public void addScriptField(ScriptField... scriptField) {
scriptFields.addAll(Arrays.asList(scriptField));
}
public void addFacet(FacetRequest facetRequest) {
if (facets == null) {
facets = new ArrayList<>();
}
facets.add(facetRequest);
}
public void setFacets(List<FacetRequest> facets) {
this.facets = facets;
}
@Override
public List<FacetRequest> getFacets() {
return facets;
}
@Override
public List<AbstractAggregationBuilder> getAggregations() {
return aggregations;
}
public void addAggregation(AbstractAggregationBuilder aggregationBuilder) {
if (aggregations == null) {
aggregations = new ArrayList<>();
}
aggregations.add(aggregationBuilder);
}
public void setAggregations(List<AbstractAggregationBuilder> aggregations) {
this.aggregations = aggregations;
}
@Override
public List<IndexBoost> getIndicesBoost() {
return indicesBoost;
}
public void setIndicesBoost(List<IndexBoost> indicesBoost) {
this.indicesBoost = indicesBoost;
}
}

Some files were not shown because too many files have changed in this diff Show More