Skip to content

Commit 25b323c

Browse files
authored
source_filter and fields fixes.
Original Pull Request #1819 Closes #1817
1 parent 33bc36d commit 25b323c

File tree

7 files changed

+48
-78
lines changed

7 files changed

+48
-78
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[[elasticsearch-migration-guide-4.2-4.3]]
2+
= Upgrading from 4.2.x to 4.3.x
3+
4+
This section describes breaking changes from version 4.2.x to 4.3.x and how removed features can be replaced by new introduced features.
5+
6+
[[elasticsearch-migration-guide-4.2-4.3.deprecations]]
7+
== Deprecations
8+
9+
[[elasticsearch-migration-guide-4.2-4.3.breaking-changes]]
10+
== Breaking Changes
11+
12+
=== Handling of field and sourceFilter properties of Query
13+
14+
Up to version 4.2 the `fields` property of a `Query` was interpreted and added to the include list of the `sourceFilter`. This was not correct, as these are different things for Elasticsearch. This has been corrected. As a consequence code might not work anymore that relies on using `fields` to specify which fields should be returned from the document's
15+
`_source' and should be changed to use the `sourceFilter`.

src/main/asciidoc/reference/migration-guides.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ include::elasticsearch-migration-guide-3.2-4.0.adoc[]
88
include::elasticsearch-migration-guide-4.0-4.1.adoc[]
99

1010
include::elasticsearch-migration-guide-4.1-4.2.adoc[]
11+
12+
include::elasticsearch-migration-guide-4.2-4.3.adoc[]
1113
:leveloffset: -1

src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java

+20-26
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ private List<MultiGetRequest.Item> getMultiRequestItems(Query searchQuery, Class
681681
item = item.routing(searchQuery.getRoute());
682682
}
683683

684+
// note: multiGet does not have fields, need to set sourceContext to filter
684685
if (fetchSourceContext != null) {
685686
item.fetchSourceContext(fetchSourceContext);
686687
}
@@ -929,11 +930,6 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class<?> clazz
929930
sourceBuilder.seqNoAndPrimaryTerm(true);
930931
}
931932

932-
if (query.getSourceFilter() != null) {
933-
SourceFilter sourceFilter = query.getSourceFilter();
934-
sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
935-
}
936-
937933
if (query.getPageable().isPaged()) {
938934
sourceBuilder.from((int) query.getPageable().getOffset());
939935
sourceBuilder.size(query.getPageable().getPageSize());
@@ -942,8 +938,14 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class<?> clazz
942938
sourceBuilder.size(INDEX_MAX_RESULT_WINDOW);
943939
}
944940

941+
if (query.getSourceFilter() != null) {
942+
sourceBuilder.fetchSource(getFetchSourceContext(query));
943+
SourceFilter sourceFilter = query.getSourceFilter();
944+
sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
945+
}
946+
945947
if (!query.getFields().isEmpty()) {
946-
sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null);
948+
query.getFields().forEach(sourceBuilder::fetchField);
947949
}
948950

949951
if (query.getIndicesOptions() != null) {
@@ -1023,11 +1025,6 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli
10231025
searchRequestBuilder.seqNoAndPrimaryTerm(true);
10241026
}
10251027

1026-
if (query.getSourceFilter() != null) {
1027-
SourceFilter sourceFilter = query.getSourceFilter();
1028-
searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
1029-
}
1030-
10311028
if (query.getPageable().isPaged()) {
10321029
searchRequestBuilder.setFrom((int) query.getPageable().getOffset());
10331030
searchRequestBuilder.setSize(query.getPageable().getPageSize());
@@ -1036,8 +1033,13 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli
10361033
searchRequestBuilder.setSize(INDEX_MAX_RESULT_WINDOW);
10371034
}
10381035

1036+
if (query.getSourceFilter() != null) {
1037+
SourceFilter sourceFilter = query.getSourceFilter();
1038+
searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
1039+
}
1040+
10391041
if (!query.getFields().isEmpty()) {
1040-
searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null);
1042+
query.getFields().forEach(searchRequestBuilder::addFetchField);
10411043
}
10421044

10431045
if (query.getIndicesOptions() != null) {
@@ -1599,24 +1601,16 @@ public static WriteRequest.RefreshPolicy toElasticsearchRefreshPolicy(RefreshPol
15991601
}
16001602
}
16011603

1604+
@Nullable
16021605
private FetchSourceContext getFetchSourceContext(Query searchQuery) {
1603-
FetchSourceContext fetchSourceContext = null;
1604-
SourceFilter sourceFilter = searchQuery.getSourceFilter();
16051606

1606-
if (!isEmpty(searchQuery.getFields())) {
1607-
if (sourceFilter == null) {
1608-
sourceFilter = new FetchSourceFilter(toArray(searchQuery.getFields()), null);
1609-
} else {
1610-
ArrayList<String> arrayList = new ArrayList<>();
1611-
Collections.addAll(arrayList, sourceFilter.getIncludes());
1612-
sourceFilter = new FetchSourceFilter(toArray(arrayList), null);
1613-
}
1607+
SourceFilter sourceFilter = searchQuery.getSourceFilter();
16141608

1615-
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1616-
} else if (sourceFilter != null) {
1617-
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1609+
if (sourceFilter != null) {
1610+
return new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
16181611
}
1619-
return fetchSourceContext;
1612+
1613+
return null;
16201614
}
16211615

16221616
// endregion

src/main/java/org/springframework/data/elasticsearch/core/query/Query.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static Query findAll() {
9999
/**
100100
* Get fields to be returned as part of search request
101101
*
102-
* @return
102+
* @return maybe empty, never null
103103
*/
104104
List<String> getFields();
105105

src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingUnitTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
4545
import org.springframework.data.elasticsearch.core.query.Criteria;
4646
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
47-
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
47+
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
4848
import org.springframework.data.elasticsearch.core.query.Query;
4949
import org.springframework.data.elasticsearch.core.query.SourceFilter;
5050
import org.springframework.lang.Nullable;
@@ -430,7 +430,7 @@ void shouldMapNamesInSourceFieldsAndSourceFilters() {
430430
Query query = Query.findAll();
431431
// Note: we don't care if these filters make sense here, this test is only about name mapping
432432
query.addFields("firstName", "lastName");
433-
query.addSourceFilter(new FetchSourceFilter(new String[] { "firstName" }, new String[] { "lastName" }));
433+
query.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("firstName").withExcludes("lastName").build());
434434

435435
mappingElasticsearchConverter.updateQuery(query, Person.class);
436436

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java

+2-31
Original file line numberDiff line numberDiff line change
@@ -994,35 +994,6 @@ public void shouldDeleteGivenCriteriaQuery() {
994994
assertThat(sampleEntities).isEmpty();
995995
}
996996

997-
@Test
998-
public void shouldReturnSpecifiedFields() {
999-
1000-
// given
1001-
String documentId = nextIdAsString();
1002-
String message = "some test message";
1003-
String type = "some type";
1004-
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(message).type(type)
1005-
.version(System.currentTimeMillis()).location(new GeoPoint(1.2, 3.4)).build();
1006-
1007-
IndexQuery indexQuery = getIndexQuery(sampleEntity);
1008-
1009-
operations.index(indexQuery, index);
1010-
indexOperations.refresh();
1011-
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message")
1012-
.build();
1013-
1014-
// when
1015-
SearchHits<SampleEntity> searchHits = operations.search(searchQuery, SampleEntity.class, index);
1016-
1017-
// then
1018-
assertThat(searchHits).isNotNull();
1019-
assertThat(searchHits.getTotalHits()).isEqualTo(1);
1020-
final SampleEntity actual = searchHits.getSearchHit(0).getContent();
1021-
assertThat(actual.message).isEqualTo(message);
1022-
assertThat(actual.getType()).isNull();
1023-
assertThat(actual.getLocation()).isNull();
1024-
}
1025-
1026997
@Test
1027998
public void shouldReturnFieldsBasedOnSourceFilter() {
1028999

@@ -2666,7 +2637,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() {
26662637
indexOperations.refresh();
26672638

26682639
// then
2669-
SourceFilter sourceFilter = new FetchSourceFilter(new String[] { "id" }, new String[] {});
2640+
SourceFilter sourceFilter = new FetchSourceFilterBuilder().withIncludes("id").build();
26702641

26712642
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
26722643
.withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build();
@@ -3631,7 +3602,7 @@ void shouldSetScriptedFieldsOnImmutableObjects() {
36313602
Map<String, Object> params = new HashMap<>();
36323603
params.put("factor", 2);
36333604
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
3634-
.withSourceFilter(new FetchSourceFilter(new String[] { "*" }, new String[] {}))
3605+
.withSourceFilter(new FetchSourceFilterBuilder().withIncludes("*").build())
36353606
.withScriptField(new ScriptField("scriptedRate",
36363607
new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params)))
36373608
.build();

src/test/java/org/springframework/data/elasticsearch/core/SourceFilterIntegrationTests.java

+6-18
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.data.elasticsearch.annotations.Document;
3030
import org.springframework.data.elasticsearch.annotations.Field;
3131
import org.springframework.data.elasticsearch.annotations.FieldType;
32+
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
3233
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
3334
import org.springframework.data.elasticsearch.core.query.Query;
3435
import org.springframework.data.elasticsearch.core.query.SourceFilter;
@@ -66,28 +67,15 @@ void tearDown() {
6667
indexOps.delete();
6768
}
6869

69-
@Test // #1659
70-
@DisplayName("should only return requested fields on search")
71-
void shouldOnlyReturnRequestedFieldsOnSearch() {
72-
73-
Query query = Query.findAll();
74-
query.addFields("field2");
75-
76-
SearchHits<Entity> searchHits = operations.search(query, Entity.class);
77-
78-
assertThat(searchHits).hasSize(1);
79-
Entity entity = searchHits.getSearchHit(0).getContent();
80-
assertThat(entity.getField1()).isNull();
81-
assertThat(entity.getField2()).isEqualTo("two");
82-
assertThat(entity.getField3()).isNull();
83-
}
84-
8570
@Test // #1659, #1678
8671
@DisplayName("should only return requested fields on multiget")
8772
void shouldOnlyReturnRequestedFieldsOnGMultiGet() {
8873

89-
Query query = new NativeSearchQueryBuilder().withIds(Collections.singleton("42")).build();
90-
query.addFields("field2");
74+
// multiget has no fields, need sourcefilter here
75+
Query query = new NativeSearchQueryBuilder() //
76+
.withIds(Collections.singleton("42")) //
77+
.withSourceFilter(new FetchSourceFilterBuilder().withIncludes("field2").build()) //
78+
.build(); //
9179

9280
List<MultiGetItem<Entity>> entities = operations.multiGet(query, Entity.class);
9381

0 commit comments

Comments
 (0)