mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-08-17 15:03:28 +00:00
Compare commits
23 Commits
main
...
3.1.3.RELE
Author | SHA1 | Date | |
---|---|---|---|
|
70f77bfd1f | ||
|
d887b1bc9b | ||
|
6636bbb364 | ||
|
b116cce1e8 | ||
|
ed7a761912 | ||
|
b0353ec4e5 | ||
|
758e697aec | ||
|
02761a48e0 | ||
|
e6fbc37550 | ||
|
0220f69f3f | ||
|
c0dcda00e8 | ||
|
cef1fc7d77 | ||
|
9ddf4868ef | ||
|
dde561a805 | ||
|
950c48a069 | ||
|
df9954b3ef | ||
|
32d5f5dcb9 | ||
|
0191d69d94 | ||
|
e7e0983ea5 | ||
|
a299260a03 | ||
|
627d96cbfc | ||
|
efa3b4d17e | ||
|
f5d44ad755 |
6
pom.xml
6
pom.xml
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-elasticsearch</artifactId>
|
<artifactId>spring-data-elasticsearch</artifactId>
|
||||||
<version>3.1.0.RELEASE</version>
|
<version>3.1.3.RELEASE</version>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data.build</groupId>
|
<groupId>org.springframework.data.build</groupId>
|
||||||
<artifactId>spring-data-parent</artifactId>
|
<artifactId>spring-data-parent</artifactId>
|
||||||
<version>2.1.0.RELEASE</version>
|
<version>2.1.3.RELEASE</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>Spring Data Elasticsearch</name>
|
<name>Spring Data Elasticsearch</name>
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<commonslang>2.6</commonslang>
|
<commonslang>2.6</commonslang>
|
||||||
<elasticsearch>6.2.2</elasticsearch>
|
<elasticsearch>6.2.2</elasticsearch>
|
||||||
<log4j>2.9.1</log4j>
|
<log4j>2.9.1</log4j>
|
||||||
<springdata.commons>2.1.0.RELEASE</springdata.commons>
|
<springdata.commons>2.1.3.RELEASE</springdata.commons>
|
||||||
<java-module-name>spring.data.elasticsearch</java-module-name>
|
<java-module-name>spring.data.elasticsearch</java-module-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -23,50 +23,55 @@ Page<SampleEntity> sampleEntities =
|
|||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
[[elasticsearch.scan.and.scroll]]
|
[[elasticsearch.scroll]]
|
||||||
== Using Scan And Scroll For Big Result Set
|
== Using 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.
|
Elasticsearch has a scroll API for getting big result set in chunks. `ElasticsearchTemplate` has startScroll and continueScroll methods that can be used as below.
|
||||||
|
|
||||||
.Using Scan and Scroll
|
.Using startScroll and continueScroll
|
||||||
====
|
====
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||||
.withQuery(matchAllQuery())
|
.withQuery(matchAllQuery())
|
||||||
.withIndices("test-index")
|
.withIndices(INDEX_NAME)
|
||||||
.withTypes("test-type")
|
.withTypes(TYPE_NAME)
|
||||||
.withPageable(new PageRequest(0,1))
|
.withFields("message")
|
||||||
|
.withPageable(PageRequest.of(0, 10))
|
||||||
.build();
|
.build();
|
||||||
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
|
|
||||||
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
|
Page<SampleEntity> scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class);
|
||||||
boolean hasRecords = true;
|
|
||||||
while (hasRecords){
|
String scrollId = ((ScrolledPage) scroll).getScrollId();
|
||||||
Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
|
List<SampleEntity> sampleEntities = new ArrayList<>();
|
||||||
{
|
while (scroll.hasContent()) {
|
||||||
@Override
|
sampleEntities.addAll(scroll.getContent());
|
||||||
public Page<SampleEntity> mapResults(SearchResponse response) {
|
scrollId = ((ScrolledPage) scroll).getScrollId();
|
||||||
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class);
|
||||||
for(SearchHit searchHit : response.getHits()){
|
}
|
||||||
if(response.getHits().getHits().length <= 0) {
|
elasticsearchTemplate.clearScroll(scrollId);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
`ElasticsearchTemplate` additionally has the stream method which wraps the scan and scroll operations into a CloseableIterator.
|
||||||
|
|
||||||
|
.Using stream
|
||||||
|
====
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||||
|
.withQuery(matchAllQuery())
|
||||||
|
.withIndices(INDEX_NAME)
|
||||||
|
.withTypes(TYPE_NAME)
|
||||||
|
.withFields("message")
|
||||||
|
.withPageable(PageRequest.of(0, 10))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
CloseableIterator<SampleEntity> stream = elasticsearchTemplate.stream(searchQuery, SampleEntity.class);
|
||||||
|
|
||||||
|
List<SampleEntity> sampleEntities = new ArrayList<>();
|
||||||
|
while (stream.hasNext()) {
|
||||||
|
sampleEntities.add(stream.next());
|
||||||
|
}
|
||||||
|
----
|
||||||
|
====
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 the original author or authors.
|
* Copyright 2013-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -52,7 +52,11 @@ public @interface Field {
|
|||||||
|
|
||||||
String analyzer() default "";
|
String analyzer() default "";
|
||||||
|
|
||||||
|
String normalizer() default "";
|
||||||
|
|
||||||
String[] ignoreFields() default {};
|
String[] ignoreFields() default {};
|
||||||
|
|
||||||
boolean includeInParent() default false;
|
boolean includeInParent() default false;
|
||||||
|
|
||||||
|
String[] copyTo() default {};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014 the original author or authors.
|
* Copyright 2014-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,7 +21,9 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @author Artur Konczak
|
||||||
|
* @author Mohsin Husen
|
||||||
|
* @author Sascha Woo
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@ -44,4 +46,6 @@ public @interface InnerField {
|
|||||||
String searchAnalyzer() default "";
|
String searchAnalyzer() default "";
|
||||||
|
|
||||||
String analyzer() default "";
|
String analyzer() default "";
|
||||||
|
|
||||||
|
String normalizer() default "";
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,10 @@ class MappingBuilder {
|
|||||||
public static final String FIELD_FORMAT = "format";
|
public static final String FIELD_FORMAT = "format";
|
||||||
public static final String FIELD_SEARCH_ANALYZER = "search_analyzer";
|
public static final String FIELD_SEARCH_ANALYZER = "search_analyzer";
|
||||||
public static final String FIELD_INDEX_ANALYZER = "analyzer";
|
public static final String FIELD_INDEX_ANALYZER = "analyzer";
|
||||||
|
public static final String FIELD_NORMALIZER = "normalizer";
|
||||||
public static final String FIELD_PROPERTIES = "properties";
|
public static final String FIELD_PROPERTIES = "properties";
|
||||||
public static final String FIELD_PARENT = "_parent";
|
public static final String FIELD_PARENT = "_parent";
|
||||||
|
public static final String FIELD_COPY_TO = "copy_to";
|
||||||
|
|
||||||
public static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators";
|
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_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
|
||||||
@ -269,6 +271,8 @@ class MappingBuilder {
|
|||||||
String datePattern = null;
|
String datePattern = null;
|
||||||
String analyzer = null;
|
String analyzer = null;
|
||||||
String searchAnalyzer = null;
|
String searchAnalyzer = null;
|
||||||
|
String normalizer = null;
|
||||||
|
String[] copyTo = null;
|
||||||
|
|
||||||
if (annotation instanceof Field) {
|
if (annotation instanceof Field) {
|
||||||
// @Field
|
// @Field
|
||||||
@ -281,6 +285,8 @@ class MappingBuilder {
|
|||||||
datePattern = fieldAnnotation.pattern();
|
datePattern = fieldAnnotation.pattern();
|
||||||
analyzer = fieldAnnotation.analyzer();
|
analyzer = fieldAnnotation.analyzer();
|
||||||
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
||||||
|
normalizer = fieldAnnotation.normalizer();
|
||||||
|
copyTo = fieldAnnotation.copyTo();
|
||||||
} else if (annotation instanceof InnerField) {
|
} else if (annotation instanceof InnerField) {
|
||||||
// @InnerField
|
// @InnerField
|
||||||
InnerField fieldAnnotation = (InnerField) annotation;
|
InnerField fieldAnnotation = (InnerField) annotation;
|
||||||
@ -292,6 +298,7 @@ class MappingBuilder {
|
|||||||
datePattern = fieldAnnotation.pattern();
|
datePattern = fieldAnnotation.pattern();
|
||||||
analyzer = fieldAnnotation.analyzer();
|
analyzer = fieldAnnotation.analyzer();
|
||||||
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
||||||
|
normalizer = fieldAnnotation.normalizer();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField");
|
throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField");
|
||||||
}
|
}
|
||||||
@ -318,6 +325,12 @@ class MappingBuilder {
|
|||||||
if (!StringUtils.isEmpty(searchAnalyzer)) {
|
if (!StringUtils.isEmpty(searchAnalyzer)) {
|
||||||
builder.field(FIELD_SEARCH_ANALYZER, searchAnalyzer);
|
builder.field(FIELD_SEARCH_ANALYZER, searchAnalyzer);
|
||||||
}
|
}
|
||||||
|
if (!StringUtils.isEmpty(normalizer)) {
|
||||||
|
builder.field(FIELD_NORMALIZER, normalizer);
|
||||||
|
}
|
||||||
|
if (copyTo != null && copyTo.length > 0) {
|
||||||
|
builder.field(FIELD_COPY_TO, copyTo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isEntity(java.lang.reflect.Field field) {
|
protected static boolean isEntity(java.lang.reflect.Field field) {
|
||||||
|
@ -35,13 +35,25 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
|
|||||||
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
|
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
|
||||||
* implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should
|
* implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should
|
||||||
* rather call {@link ElasticsearchPersistentEntity#isScoreProperty(PersistentProperty)} to determine whether the
|
* rather call {@link ElasticsearchPersistentEntity#isScoreProperty(PersistentProperty)} to determine whether the
|
||||||
* current property is the version property of that {@link ElasticsearchPersistentEntity} under consideration.
|
* current property is the score property of that {@link ElasticsearchPersistentEntity} under consideration.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
boolean isScoreProperty();
|
boolean isScoreProperty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the current property is a <em>potential</em> parent property of the owning
|
||||||
|
* {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity}
|
||||||
|
* implementation to discover parent property candidates on {@link ElasticsearchPersistentEntity} creation you should
|
||||||
|
* rather call {@link ElasticsearchPersistentEntity#isParentProperty()} to determine whether the current property is
|
||||||
|
* the parent property of that {@link ElasticsearchPersistentEntity} under consideration.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
boolean isParentProperty();
|
||||||
|
|
||||||
public enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> {
|
public enum PropertyToFieldNameConverter implements Converter<ElasticsearchPersistentProperty, String> {
|
||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
@ -170,18 +170,18 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
|||||||
public void addPersistentProperty(ElasticsearchPersistentProperty property) {
|
public void addPersistentProperty(ElasticsearchPersistentProperty property) {
|
||||||
super.addPersistentProperty(property);
|
super.addPersistentProperty(property);
|
||||||
|
|
||||||
Parent annotation = property.findAnnotation(Parent.class);
|
if (property.isParentProperty()) {
|
||||||
|
ElasticsearchPersistentProperty parentProperty = this.parentIdProperty;
|
||||||
|
|
||||||
if (annotation != null) {
|
if (parentProperty != null) {
|
||||||
Assert.isNull(this.parentIdProperty, "Only one field can hold a @Parent annotation");
|
throw new MappingException(
|
||||||
Assert.isNull(this.parentType, "Only one field can hold a @Parent annotation");
|
String.format("Attempt to add parent property %s but already have property %s registered "
|
||||||
Assert.isTrue(property.getType() == String.class, "Parent ID property should be String");
|
+ "as parent property. Check your mapping configuration!", property.getField(), parentProperty.getField()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Parent parentAnnotation = property.findAnnotation(Parent.class);
|
||||||
this.parentIdProperty = property;
|
this.parentIdProperty = property;
|
||||||
this.parentType = annotation.type();
|
this.parentType = parentAnnotation.type();
|
||||||
}
|
|
||||||
|
|
||||||
if (property.isVersionProperty()) {
|
|
||||||
Assert.isTrue(property.getType() == Long.class, "Version property must be of type Long!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.isScoreProperty()) {
|
if (property.isScoreProperty()) {
|
||||||
@ -191,7 +191,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
|||||||
if (scoreProperty != null) {
|
if (scoreProperty != null) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
String.format("Attempt to add score property %s but already have property %s registered "
|
String.format("Attempt to add score property %s but already have property %s registered "
|
||||||
+ "as version. Check your mapping configuration!", property.getField(), scoreProperty.getField()));
|
+ "as score property. Check your mapping configuration!", property.getField(), scoreProperty.getField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scoreProperty = property;
|
this.scoreProperty = property;
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
package org.springframework.data.elasticsearch.core.mapping;
|
package org.springframework.data.elasticsearch.core.mapping;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Parent;
|
||||||
import org.springframework.data.elasticsearch.annotations.Score;
|
import org.springframework.data.elasticsearch.annotations.Score;
|
||||||
import org.springframework.data.mapping.Association;
|
import org.springframework.data.mapping.Association;
|
||||||
import org.springframework.data.mapping.MappingException;
|
import org.springframework.data.mapping.MappingException;
|
||||||
@ -39,39 +39,57 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
|||||||
public class SimpleElasticsearchPersistentProperty extends
|
public class SimpleElasticsearchPersistentProperty extends
|
||||||
AnnotationBasedPersistentProperty<ElasticsearchPersistentProperty> implements ElasticsearchPersistentProperty {
|
AnnotationBasedPersistentProperty<ElasticsearchPersistentProperty> implements ElasticsearchPersistentProperty {
|
||||||
|
|
||||||
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<>();
|
private static final List<String> SUPPORTED_ID_PROPERTY_NAMES = Arrays.asList("id", "document");
|
||||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<>();
|
|
||||||
|
|
||||||
private final boolean isScore;
|
|
||||||
|
|
||||||
static {
|
private final boolean isScore;
|
||||||
SUPPORTED_ID_TYPES.add(String.class);
|
private final boolean isParent;
|
||||||
SUPPORTED_ID_PROPERTY_NAMES.add("id");
|
private final boolean isId;
|
||||||
SUPPORTED_ID_PROPERTY_NAMES.add("documentId");
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimpleElasticsearchPersistentProperty(Property property,
|
public SimpleElasticsearchPersistentProperty(Property property,
|
||||||
PersistentEntity<?, ElasticsearchPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
PersistentEntity<?, ElasticsearchPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||||
|
|
||||||
super(property, owner, simpleTypeHolder);
|
super(property, owner, simpleTypeHolder);
|
||||||
|
|
||||||
|
this.isId = super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName());
|
||||||
this.isScore = isAnnotationPresent(Score.class);
|
this.isScore = isAnnotationPresent(Score.class);
|
||||||
|
this.isParent = isAnnotationPresent(Parent.class);
|
||||||
|
|
||||||
|
if (isVersionProperty() && getType() != Long.class) {
|
||||||
|
throw new MappingException(String.format("Version property %s must be of type Long!", property.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
if (isScore && !Arrays.asList(Float.TYPE, Float.class).contains(getType())) {
|
if (isScore && !Arrays.asList(Float.TYPE, Float.class).contains(getType())) {
|
||||||
throw new MappingException(String.format("Score property %s must be either of type float or Float!", property.getName()));
|
throw new MappingException(
|
||||||
|
String.format("Score property %s must be either of type float or Float!", property.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isParent && getType() != String.class) {
|
||||||
|
throw new MappingException(String.format("Parent property %s must be of type String!", property.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty#getFieldName()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getFieldName() {
|
public String getFieldName() {
|
||||||
return getProperty().getName();
|
return getProperty().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isIdProperty()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isIdProperty() {
|
public boolean isIdProperty() {
|
||||||
return super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName());
|
return isId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation()
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Association<ElasticsearchPersistentProperty> createAssociation() {
|
protected Association<ElasticsearchPersistentProperty> createAssociation() {
|
||||||
return null;
|
return null;
|
||||||
@ -85,7 +103,7 @@ public class SimpleElasticsearchPersistentProperty extends
|
|||||||
public boolean isScoreProperty() {
|
public boolean isScoreProperty() {
|
||||||
return isScore;
|
return isScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#isImmutable()
|
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#isImmutable()
|
||||||
@ -94,4 +112,13 @@ public class SimpleElasticsearchPersistentProperty extends
|
|||||||
public boolean isImmutable() {
|
public boolean isImmutable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty#isParentProperty()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isParentProperty() {
|
||||||
|
return isParent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,47 @@
|
|||||||
Spring Data Elasticsearch Changelog
|
Spring Data Elasticsearch Changelog
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
Changes in version 3.1.3.RELEASE (2018-11-27)
|
||||||
|
---------------------------------------------
|
||||||
|
* DATAES-503 - Missing copy_to property in @Field Annotation.
|
||||||
|
* DATAES-496 - Release 3.1.3 (Lovelace SR3).
|
||||||
|
* DATAES-492 - Missing normalizer property in @Field and @InnerField Annotation.
|
||||||
|
* DATAES-445 - Usage example of scan and scroll is misleading.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 3.0.12.RELEASE (2018-11-27)
|
||||||
|
----------------------------------------------
|
||||||
|
* DATAES-503 - Missing copy_to property in @Field Annotation.
|
||||||
|
* DATAES-492 - Missing normalizer property in @Field and @InnerField Annotation.
|
||||||
|
* DATAES-490 - Release 3.0.12 (Kay SR12).
|
||||||
|
* DATAES-445 - Usage example of scan and scroll is misleading.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 2.1.17.RELEASE (2018-11-27)
|
||||||
|
----------------------------------------------
|
||||||
|
* DATAES-491 - Release 2.1.17 (Ingalls SR17).
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 3.1.2.RELEASE (2018-10-29)
|
||||||
|
---------------------------------------------
|
||||||
|
* DATAES-489 - Release 3.1.2 (Lovelace SR2).
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 2.1.16.RELEASE (2018-10-15)
|
||||||
|
----------------------------------------------
|
||||||
|
* DATAES-484 - Release 2.1.16 (Ingalls SR16).
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 3.0.11.RELEASE (2018-10-15)
|
||||||
|
----------------------------------------------
|
||||||
|
* DATAES-485 - Release 3.0.11 (Kay SR11).
|
||||||
|
|
||||||
|
|
||||||
|
Changes in version 3.1.1.RELEASE (2018-10-15)
|
||||||
|
---------------------------------------------
|
||||||
|
* DATAES-486 - Release 3.1.1 (Lovelace SR1).
|
||||||
|
|
||||||
|
|
||||||
Changes in version 3.1.0.RELEASE (2018-09-21)
|
Changes in version 3.1.0.RELEASE (2018-09-21)
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
* DATAES-480 - Release 3.1 GA (Lovelace).
|
* DATAES-480 - Release 3.1 GA (Lovelace).
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Spring Data Elasticsearch 3.1 GA
|
Spring Data Elasticsearch 3.1.3
|
||||||
Copyright (c) [2013-2016] Pivotal Software, Inc.
|
Copyright (c) [2013-2016] Pivotal Software, Inc.
|
||||||
|
|
||||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
@ -23,6 +23,7 @@ import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -31,11 +32,21 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
import org.springframework.data.elasticsearch.builder.SampleInheritedEntityBuilder;
|
import org.springframework.data.elasticsearch.builder.SampleInheritedEntityBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
||||||
import org.springframework.data.elasticsearch.entities.*;
|
import org.springframework.data.elasticsearch.entities.Book;
|
||||||
|
import org.springframework.data.elasticsearch.entities.CopyToEntity;
|
||||||
import org.springframework.data.elasticsearch.entities.GeoEntity;
|
import org.springframework.data.elasticsearch.entities.GeoEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.Group;
|
||||||
|
import org.springframework.data.elasticsearch.entities.MinimalEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.NormalizerEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.SampleInheritedEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.SampleTransientEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.SimpleRecursiveEntity;
|
||||||
|
import org.springframework.data.elasticsearch.entities.StockPrice;
|
||||||
|
import org.springframework.data.elasticsearch.entities.User;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
@ -45,6 +56,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
* @author Keivn Leturc
|
* @author Keivn Leturc
|
||||||
* @author Nordine Bittich
|
* @author Nordine Bittich
|
||||||
|
* @author Sascha Woo
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
||||||
@ -215,4 +227,45 @@ public class MappingBuilderTests {
|
|||||||
assertThat(descriptionMapping.get("type"), equalTo("text"));
|
assertThat(descriptionMapping.get("type"), equalTo("text"));
|
||||||
assertThat(descriptionMapping.get("analyzer"), equalTo("whitespace"));
|
assertThat(descriptionMapping.get("analyzer"), equalTo("whitespace"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-492
|
||||||
|
public void shouldUseKeywordNormalizer() throws IOException {
|
||||||
|
|
||||||
|
// given
|
||||||
|
elasticsearchTemplate.deleteIndex(NormalizerEntity.class);
|
||||||
|
elasticsearchTemplate.createIndex(NormalizerEntity.class);
|
||||||
|
elasticsearchTemplate.putMapping(NormalizerEntity.class);
|
||||||
|
|
||||||
|
// when
|
||||||
|
Map mapping = elasticsearchTemplate.getMapping(NormalizerEntity.class);
|
||||||
|
Map properties = (Map) mapping.get("properties");
|
||||||
|
Map fieldName = (Map) properties.get("name");
|
||||||
|
Map fieldDescriptionLowerCase = (Map) ((Map) ((Map) properties.get("description")).get("fields")).get("lower_case");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(fieldName.get("type"), equalTo("keyword"));
|
||||||
|
assertThat(fieldName.get("normalizer"), equalTo("lower_case_normalizer"));
|
||||||
|
assertThat(fieldDescriptionLowerCase.get("type"), equalTo("keyword"));
|
||||||
|
assertThat(fieldDescriptionLowerCase.get("normalizer"), equalTo("lower_case_normalizer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-503
|
||||||
|
public void shouldUseCopyTo() throws IOException {
|
||||||
|
|
||||||
|
// given
|
||||||
|
elasticsearchTemplate.deleteIndex(CopyToEntity.class);
|
||||||
|
elasticsearchTemplate.createIndex(CopyToEntity.class);
|
||||||
|
elasticsearchTemplate.putMapping(CopyToEntity.class);
|
||||||
|
|
||||||
|
// when
|
||||||
|
Map mapping = elasticsearchTemplate.getMapping(CopyToEntity.class);
|
||||||
|
Map properties = (Map) mapping.get("properties");
|
||||||
|
Map fieldFirstName = (Map) properties.get("firstName");
|
||||||
|
Map fieldLastName = (Map) properties.get("lastName");
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<String> copyToValue = Arrays.asList("name");
|
||||||
|
assertThat(fieldFirstName.get("copy_to"), equalTo(copyToValue));
|
||||||
|
assertThat(fieldLastName.get("copy_to"), equalTo(copyToValue));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ import org.springframework.util.ReflectionUtils;
|
|||||||
*/
|
*/
|
||||||
public class SimpleElasticsearchPersistentEntityTests {
|
public class SimpleElasticsearchPersistentEntityTests {
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = MappingException.class)
|
||||||
public void shouldThrowExceptionGivenVersionPropertyIsNotLong() throws NoSuchFieldException, IntrospectionException {
|
public void shouldThrowExceptionGivenVersionPropertyIsNotLong() throws NoSuchFieldException, IntrospectionException {
|
||||||
// given
|
// given
|
||||||
TypeInformation typeInformation = ClassTypeInformation.from(EntityWithWrongVersionType.class);
|
TypeInformation typeInformation = ClassTypeInformation.from(EntityWithWrongVersionType.class);
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.entities;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Sascha Woo
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Document(indexName = "test-copy-to", type = "test", shards = 1, replicas = 0, refreshInterval = "-1")
|
||||||
|
public class CopyToEntity {
|
||||||
|
|
||||||
|
@Id private String id;
|
||||||
|
|
||||||
|
@Field(type = FieldType.Keyword, copyTo = "name") private String firstName;
|
||||||
|
|
||||||
|
@Field(type = FieldType.Keyword, copyTo = "name") private String lastName;
|
||||||
|
|
||||||
|
@Field(type = FieldType.Keyword) private String name;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.entities;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.InnerField;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Sascha Woo
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Document(indexName = "test-index-normalizer", type = "test", shards = 1, replicas = 0, refreshInterval = "-1")
|
||||||
|
@Setting(settingPath = "/settings/test-normalizer.json")
|
||||||
|
public class NormalizerEntity {
|
||||||
|
|
||||||
|
@Id private String id;
|
||||||
|
|
||||||
|
@Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case",
|
||||||
|
type = FieldType.Keyword, normalizer = "lower_case_normalizer") })
|
||||||
|
private String description;
|
||||||
|
}
|
13
src/test/resources/settings/test-normalizer.json
Normal file
13
src/test/resources/settings/test-normalizer.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"index": {
|
||||||
|
"analysis": {
|
||||||
|
"normalizer": {
|
||||||
|
"lower_case_normalizer": {
|
||||||
|
"type": "custom",
|
||||||
|
"char_filter": [],
|
||||||
|
"filter": [ "lowercase" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user