Closed
Description
Having a repository with a custom method:
@Query("{\"ids\": {\"values\": ?0 }}")
Stream<T> findAllByIdStream(Iterable<String> ids);
and calling it with IDs that contain backslashes:
repository.findAllByIdStream(List.of("Test\\id1", "Test\\id2"));
will be translated to this request:
"POST /elastic-testdata/_search?scroll=60000ms&typed_keys=true&max_concurrent_shard_requests=5&search_type=query_then_fetch&batched_reduce_size=512 HTTP/1.1[\r][\n]"
"X-Elastic-Client-Meta: es=7.17.4p,jv=11,t=7.17.4p,hc=4.1.5[\r][\n]"
"Content-Length: 145[\r][\n]"
"Content-Type: application/json[\r][\n]"
"Host: localhost:9200[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: elasticsearch-java/7.17.4-SNAPSHOT (Java/11.0.16.1)[\r][\n]"
"[\r][\n]"
"{"from":0,"size":500,"query":{"wrapper":{"query":"eyJpZHMiOiB7InZhbHVlcyI6IFsiVGVzdFxpZDEiLCJUZXN0XGlkMiJdIH19"}},"version":true,"explain":false}"
with the query decoded being:
{"ids": {"values": ["Test\id1","Test\id2"] }}
resulting in an elastic error:
"HTTP/1.1 400 Bad Request[\r][\n]"
"X-elastic-product: Elasticsearch[\r][\n]"
"content-type: application/json; charset=UTF-8[\r][\n]"
"content-length: 504[\r][\n]"
"[\r][\n]"
"{"error":{"root_cause":[{"type":"parsing_exception","reason":"[1:21] [ids] failed to parse field [values]","line":1,"col":21}],"type":"parsing_exception","reason":"[1:21] [ids] failed to parse field [values]","line":1,"col":21,"caused_by":{"type":"x_content_parse_exception","reason":"[1:21] [ids] failed to parse field [values]","caused_by":{"type":"json_parse_exception","reason":"Unrecognized character escape 'i' (code 105)\n at [Source: (ByteArrayInputStream); line: 1, column: 28]"}}},"status":400}"
HTTP/1.1 400 Bad Request
X-elastic-product: Elasticsearch
content-type: application/json; charset=UTF-8
content-length: 504
The problem here is the backslash!
Executing that same query in elastic directly:
{"query":
{"ids": {"values": ["Test\id1","Test\id2"] }}
}
returns:
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "[3:21] [ids] failed to parse field [values]",
"line": 3,
"col": 21
}
],
"type": "parsing_exception",
"reason": "[3:21] [ids] failed to parse field [values]",
"line": 3,
"col": 21,
"caused_by": {
"type": "x_content_parse_exception",
"reason": "[3:21] [ids] failed to parse field [values]",
"caused_by": {
"type": "json_parse_exception",
"reason": "Unrecognized character escape 'i' (code 105)\n at [Source: (org.elasticsearch.common.io.stream.ByteBufferStreamInput); line: 3, column: 28]"
}
}
},
"status": 400
}
Using escaped backslashes does work:
{"query":
{"ids": {"values": ["Test\\id1","Test\\id2"] }}
}
And would return the results:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "elastic-testdata",
"_type": "_doc",
"_id": "Test\\id1",
"_score": 1,
"_source": {
"_class": "**********",
"name": "Name1",
"id": "Test\\id1"
}
}
]
}
}
Found with spring-boot 2.7.1 (using spring-boot-starter-data-elasticsearch) and still happening at 2.7.4.