Skip to content

[5.1] Returned values of runtime fields are null for every field except the last one #2727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shahzebklp opened this issue Oct 12, 2023 · 4 comments
Labels
type: bug A general bug

Comments

@shahzebklp
Copy link

shahzebklp commented Oct 12, 2023

I am adding runtime fields to my NativeQuery object like this:

public void addRuntimeFieldsToQuery(NativeQuery query) {
  String field1 = "runtimeField1";
  String field2 = "runtimeField2";

  query.addRuntimeField(new RuntimeField(field1, "keyword", getScript(field1)));
  query.addRuntimeField(new RuntimeField(field2, "keyword", getScript(field2)));

  query.addFields(field1, field2);
}

When I do the query I can see in my debugger that both fields and runtimeFields lists are populated just like I expect them to be in the query. However, when I get the search result only the last field's, i.e. field2, value is non-null – the rest are null. If I change the order of the last line to be query.addFields(field2, field1), then only field1's value is non-null.

This started happening after upgrading to Spring Boot 3 and the new client libraries

import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.*;

I am also using import org.springframework.data.elasticsearch.core.ElasticsearchOperations for doing the search.
I am on Spring Boot version 3.1.0 and spring-data-elasticsearch 5.1.0.

At this point I am suspecting something in the spring api is behaving differently than what it used to in Spring Boot 2.x. I have tested this for both SB2 and SB3 and Elasticsearch 7.17.7 and 8.10.3, and this issue is only showing up in SB3.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 12, 2023
@sothawo
Copy link
Collaborator

sothawo commented Oct 13, 2023

I cannot reproduce that. I just added this test to org.springframework.data.elasticsearch.core.query.scriptedandruntimefields.ScriptedAndRuntimeFieldsIntegrationTests

	@Test // #2727
	@DisplayName("should return runtime fields values")
	void shouldReturnRuntimeFieldsValues() {

		var entity = new SAREntity();
		entity.setId("42");
		entity.setValue(3);

		repository.save(entity);

		var runtimeField1 = getRuntimeField("scriptedValue1", 2);
		var runtimeField2 = getRuntimeField("scriptedValue2", 3);

		var query = CriteriaQuery.builder(Criteria.where("value").is(3)).build();
		query.addRuntimeField(runtimeField1);
		query.addRuntimeField(runtimeField2);
		query.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("*").build());
		query.addFields("scriptedValue1", "scriptedValue2");
		var searchHits = operations.search(query, SAREntity.class);

		assertThat(searchHits.getTotalHits()).isEqualTo(1);
		var foundEntity = searchHits.getSearchHit(0).getContent();
		assertThat(foundEntity.value).isEqualTo(3);
		assertThat(foundEntity.getScriptedValue1()).isEqualTo(6);
		assertThat(foundEntity.getScriptedValue2()).isEqualTo(9);
	}

and no matter in which order I add the values in addFields, it works.

The entity is defined as:

	@Document(indexName = "#{@indexNameProvider.indexName()}-sar")
	public static class SAREntity {
		@Nullable private String id;
		@Field(type = FieldType.Integer)
		@Nullable Integer value;
		@ScriptedField
		@Nullable Integer scriptedValue1;
		@ScriptedField
		@Nullable Integer scriptedValue2;
                // getter and setter omitted
}

the method creating the runtime fields:

private static RuntimeField getRuntimeField(String fieldName, int factor) {
		return new RuntimeField(
				fieldName,
				"long",
				String.format("emit(doc['value'].size() > 0 ? doc['value'].value * %d : 0)", factor));
	}

The request body sent to elElasticsearch:

{
	"_source": {
		"excludes": [],
		"includes": [
			"*"
		]
	},
	"fields": [
		{
			"field": "scriptedValue1"
		},
		{
			"field": "scriptedValue2"
		}
	],
	"from": 0,
	"query": {
		"bool": {
			"must": [
				{
					"query_string": {
						"default_operator": "and",
						"fields": [
							"value"
						],
						"query": "3"
					}
				}
			]
		}
	},
	"runtime_mappings": {
		"scriptedValue1": {
			"script": {
				"source": "emit(doc['value'].size() > 0 ? doc['value'].value * 2 : 0)"
			},
			"type": "long"
		},
		"scriptedValue2": {
			"script": {
				"source": "emit(doc['value'].size() > 0 ? doc['value'].value * 3 : 0)"
			},
			"type": "long"
		}
	},
	"size": 10,
	"track_scores": false,
	"version": true
}

the response:

{
	"took": 352,
	"timed_out": false,
	"_shards": {
		"total": 1,
		"successful": 1,
		"skipped": 0,
		"failed": 0
	},
	"hits": {
		"total": {
			"value": 1,
			"relation": "eq"
		},
		"max_score": 1.0,
		"hits": [
			{
				"_index": "scripted-runtime-1-sar",
				"_id": "42",
				"_version": 1,
				"_score": 1.0,
				"_source": {
					"_class": "org.springframework.data.elasticsearch.core.query.scriptedandruntimefields.ScriptedAndRuntimeFieldsIntegrationTests$SAREntity",
					"id": "42",
					"value": 3
				},
				"fields": {
					"scriptedValue1": [
						6
					],
					"scriptedValue2": [
						9
					]
				}
			}
		]
	}
}

@sothawo sothawo added the status: waiting-for-feedback We need additional information before we can continue label Oct 13, 2023
@sothawo
Copy link
Collaborator

sothawo commented Oct 13, 2023

Just had another look, this is a bug in the 5.1 branch, for the upcoming 5.2 version this was fixed with #2663

@sothawo sothawo changed the title Returned values of runtime fields are null for every field except the last one [5.1] Returned values of runtime fields are null for every field except the last one Oct 13, 2023
@sothawo sothawo added type: bug A general bug and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels Oct 13, 2023
sothawo added a commit to sothawo/spring-data-elasticsearch that referenced this issue Oct 14, 2023
sothawo added a commit that referenced this issue Oct 14, 2023
@sothawo sothawo closed this as completed Oct 14, 2023
@sothawo sothawo added this to the 5.1.6 (2023.0.6) milestone Oct 14, 2023
sothawo added a commit that referenced this issue Oct 14, 2023
Original Pull Request #2739
Closes #2727

(cherry picked from commit f087d5a)
@shahzebklp
Copy link
Author

I see you added this to the 5.1.6 milestone, does that mean the fix will be part of that release?

@sothawo
Copy link
Collaborator

sothawo commented Oct 17, 2023

@shahzebklp yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants