mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-04 17:52:11 +00:00
DATAES-278 - Fix documentation for created queries from repository method names.
Original PR: #371
This commit is contained in:
parent
bd047776e2
commit
e2d4ed96c8
@ -8,7 +8,7 @@ The Elasticsearch module supports all basic query building feature as string que
|
|||||||
|
|
||||||
=== Declared queries
|
=== 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>> ).
|
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 use of the `@Query` annotation (see <<elasticsearch.query-methods.at-query>> ).
|
||||||
|
|
||||||
[[elasticsearch.query-methods.criterions]]
|
[[elasticsearch.query-methods.criterions]]
|
||||||
== Query creation
|
== Query creation
|
||||||
@ -29,12 +29,14 @@ The method name above will be translated into the following Elasticsearch json q
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
----
|
----
|
||||||
{ "bool" :
|
{
|
||||||
{ "must" :
|
"query": {
|
||||||
[
|
"bool" : {
|
||||||
{ "field" : {"name" : "?"} },
|
"must" : [
|
||||||
{ "field" : {"price" : "?"} }
|
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
|
||||||
]
|
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
@ -48,80 +50,184 @@ A list of supported keywords for Elasticsearch is shown below.
|
|||||||
| Sample
|
| Sample
|
||||||
| Elasticsearch Query String| `And`
|
| Elasticsearch Query String| `And`
|
||||||
| `findByNameAndPrice`
|
| `findByNameAndPrice`
|
||||||
| `{"bool" : {"must" : [ {"field" : {"name" : "?"}},
|
| `{ "query" : {
|
||||||
{"field" : {"price" : "?"}} ]}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Or`
|
| `Or`
|
||||||
| `findByNameOrPrice`
|
| `findByNameOrPrice`
|
||||||
| `{"bool" : {"should" : [ {"field" : {"name" : "?"}},
|
| `{ "query" : {
|
||||||
{"field" : {"price" : "?"}} ]}}`
|
"bool" : {
|
||||||
|
"should" : [
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Is`
|
| `Is`
|
||||||
| `findByName`
|
| `findByName`
|
||||||
| `{"bool" : {"must" : {"field" : {"name" : "?"}}}}`
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Not`
|
| `Not`
|
||||||
| `findByNameNot`
|
| `findByNameNot`
|
||||||
| `{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}`
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must_not" : [
|
||||||
|
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Between`
|
| `Between`
|
||||||
| `findByPriceBetween`
|
| `findByPriceBetween`
|
||||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
| `{ "query" : {
|
||||||
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
|
| `LessThan`
|
||||||
|
| `findByPriceLessThan`
|
||||||
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `LessThanEqual`
|
| `LessThanEqual`
|
||||||
| `findByPriceLessThan`
|
| `findByPriceLessThanEqual`
|
||||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
| `{ "query" : {
|
||||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
"bool" : {
|
||||||
true}}}}}`
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
|
| `GreaterThan`
|
||||||
|
| `findByPriceGreaterThan`
|
||||||
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
|
|
||||||
| `GreaterThanEqual`
|
| `GreaterThanEqual`
|
||||||
| `findByPriceGreaterThan`
|
| `findByPriceGreaterThan`
|
||||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
| `{ "query" : {
|
||||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
"bool" : {
|
||||||
true}}}}}`
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Before`
|
| `Before`
|
||||||
| `findByPriceBefore`
|
| `findByPriceBefore`
|
||||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
| `{ "query" : {
|
||||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
"bool" : {
|
||||||
true}}}}}`
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `After`
|
| `After`
|
||||||
| `findByPriceAfter`
|
| `findByPriceAfter`
|
||||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
| `{ "query" : {
|
||||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
"bool" : {
|
||||||
true}}}}}`
|
"must" : [
|
||||||
|
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Like`
|
| `Like`
|
||||||
| `findByNameLike`
|
| `findByNameLike`
|
||||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
| `{ "query" : {
|
||||||
"?*","analyze_wildcard" : true}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `StartingWith`
|
| `StartingWith`
|
||||||
| `findByNameStartingWith`
|
| `findByNameStartingWith`
|
||||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
| `{ "query" : {
|
||||||
"?*","analyze_wildcard" : true}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `EndingWith`
|
| `EndingWith`
|
||||||
| `findByNameEndingWith`
|
| `findByNameEndingWith`
|
||||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
| `{ "query" : {
|
||||||
"*?","analyze_wildcard" : true}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Contains/Containing`
|
| `Contains/Containing`
|
||||||
| `findByNameContaining`
|
| `findByNameContaining`
|
||||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
| `{ "query" : {
|
||||||
"*?*","analyze_wildcard" : true}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "\*?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `In`
|
| `In`
|
||||||
| `findByNameIn(Collection<String>names)`
|
| `findByNameIn(Collection<String>names)`
|
||||||
| `{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
|
| `{ "query" : {
|
||||||
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{"bool" : {"must" : [
|
||||||
|
{"terms" : {"name" : ["?","?"]}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `NotIn`
|
| `NotIn`
|
||||||
| `findByNameNotIn(Collection<String>names)`
|
| `findByNameNotIn(Collection<String>names)`
|
||||||
| `{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
|
| `{ "query" : {
|
||||||
{"name" : "?"}}}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{"bool" : {"must_not" : [
|
||||||
|
{"terms" : {"name" : ["?","?"]}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `Near`
|
| `Near`
|
||||||
| `findByStoreNear`
|
| `findByStoreNear`
|
||||||
@ -129,16 +235,35 @@ A list of supported keywords for Elasticsearch is shown below.
|
|||||||
|
|
||||||
| `True`
|
| `True`
|
||||||
| `findByAvailableTrue`
|
| `findByAvailableTrue`
|
||||||
| `{"bool" : {"must" : {"field" : {"available" : true}}}}`
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `False`
|
| `False`
|
||||||
| `findByAvailableFalse`
|
| `findByAvailableFalse`
|
||||||
| `{"bool" : {"must" : {"field" : {"available" : false}}}}`
|
| `{ "query" : {
|
||||||
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "false", "fields" : [ "available" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}}`
|
||||||
|
|
||||||
| `OrderBy`
|
| `OrderBy`
|
||||||
| `findByAvailableTrueOrderByNameDesc`
|
| `findByAvailableTrueOrderByNameDesc`
|
||||||
| `{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
|
| `{ "query" : {
|
||||||
{"must" : {"field" : {"available" : true}}}}`
|
"bool" : {
|
||||||
|
"must" : [
|
||||||
|
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}, "sort":[{"name":{"order":"desc"}}]
|
||||||
|
}`
|
||||||
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[elasticsearch.query-methods.at-query]]
|
[[elasticsearch.query-methods.at-query]]
|
||||||
|
@ -0,0 +1,589 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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
|
||||||
|
*
|
||||||
|
* https://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.mockito.Mockito.*;
|
||||||
|
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
|
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||||
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||||
|
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||||
|
import org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery;
|
||||||
|
import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod;
|
||||||
|
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||||
|
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||||
|
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link ElasticsearchPartQuery}. Resides in the core package, as we need an instance of the
|
||||||
|
* {@link RequestFactory} class for the tests. The tests make sure that queries are built according to the method
|
||||||
|
* naming.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class ElasticsearchPartQueryTests {
|
||||||
|
|
||||||
|
public static final String BOOK_TITLE = "Title";
|
||||||
|
public static final int BOOK_PRICE = 42;
|
||||||
|
|
||||||
|
private @Mock ElasticsearchOperations operations;
|
||||||
|
private ElasticsearchConverter converter;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
converter = new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext());
|
||||||
|
when(operations.getElasticsearchConverter()).thenReturn(converter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByName() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByName";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameNot() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameNot";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must_not\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameLike() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameLike";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE
|
||||||
|
+ "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameStartingWith() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameStartingWith";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE
|
||||||
|
+ "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameEndingWith() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameEndingWith";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"*" + BOOK_TITLE
|
||||||
|
+ "\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameContaining() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameContaining";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"*" + BOOK_TITLE
|
||||||
|
+ "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameIn() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameIn";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Collection.class };
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
names.add(BOOK_TITLE);
|
||||||
|
names.add(BOOK_TITLE + "2");
|
||||||
|
Object[] parameters = new Object[] { names };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"bool\" : {\"must\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1)
|
||||||
|
+ "\"]}}]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameNotIn() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameNotIn";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Collection.class };
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
names.add(BOOK_TITLE);
|
||||||
|
names.add(BOOK_TITLE + "2");
|
||||||
|
Object[] parameters = new Object[] { names };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"bool\" : {\"must_not\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1)
|
||||||
|
+ "\"]}}]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPrice() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPrice";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { 42 };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameAndPrice() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameAndPrice";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class, Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE, BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}," + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByNameOrPrice() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByNameOrPrice";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { String.class, Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_TITLE, BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"should\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}," + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceBetween() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceBetween";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class, Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE - 10, BOOK_PRICE + 10 };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : 32, \"to\" : 52, \"include_lower\" : true, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceLessThan() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceLessThan";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : false } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceLessThanEqual() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceLessThanEqual";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceGreaterThan() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceGreaterThan";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : false, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceGreaterThanEqual() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceGreaterThanEqual";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : true, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceBefore() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceBefore";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByPriceAfter() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByPriceAfter";
|
||||||
|
Class<?>[] parameterClasses = new Class[] { Integer.class };
|
||||||
|
Object[] parameters = new Object[] { BOOK_PRICE };
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : true, \"include_upper\" : true } } }"
|
||||||
|
+ //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByAvailableTrue() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByAvailableTrue";
|
||||||
|
Class<?>[] parameterClasses = new Class[] {};
|
||||||
|
Object[] parameters = new Object[] {};
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"true\", \"fields\" : [\"available^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByAvailableFalse() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByAvailableFalse";
|
||||||
|
Class<?>[] parameterClasses = new Class[] {};
|
||||||
|
Object[] parameters = new Object[] {};
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"false\", \"fields\" : [\"available^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}}"; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void findByAvailableTrueOrderByNameDesc() throws NoSuchMethodException, JSONException {
|
||||||
|
String methodName = "findByAvailableTrueOrderByNameDesc";
|
||||||
|
Class<?>[] parameterClasses = new Class[] {};
|
||||||
|
Object[] parameters = new Object[] {};
|
||||||
|
|
||||||
|
String query = getQueryBuilder(methodName, parameterClasses, parameters);
|
||||||
|
|
||||||
|
String expected = "{\"query\": {" + //
|
||||||
|
" \"bool\" : {" + //
|
||||||
|
" \"must\" : [" + //
|
||||||
|
" {\"query_string\" : {\"query\" : \"true\", \"fields\" : [\"available^1.0\"]}}" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
"}," + //
|
||||||
|
"\"sort\":[{\"name\":{\"order\":\"desc\"}}]" + //
|
||||||
|
'}'; //
|
||||||
|
|
||||||
|
assertEquals(expected, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQueryBuilder(String methodName, Class<?>[] parameterClasses, Object[] parameters)
|
||||||
|
throws NoSuchMethodException {
|
||||||
|
Method method = SampleRepository.class.getMethod(methodName, parameterClasses);
|
||||||
|
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method,
|
||||||
|
new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||||
|
converter.getMappingContext());
|
||||||
|
ElasticsearchPartQuery partQuery = new ElasticsearchPartQuery(queryMethod, operations);
|
||||||
|
CriteriaQuery criteriaQuery = partQuery
|
||||||
|
.createQuery(new ParametersParameterAccessor(queryMethod.getParameters(), parameters));
|
||||||
|
SearchSourceBuilder source = new RequestFactory(converter)
|
||||||
|
.searchRequest(criteriaQuery, Book.class, IndexCoordinates.of("dummy")).source();
|
||||||
|
return source.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface SampleRepository extends ElasticsearchRepository<Book, String> {
|
||||||
|
List<Book> findByName(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameNot(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameLike(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameStartingWith(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameEndingWith(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameContaining(String name);
|
||||||
|
|
||||||
|
List<Book> findByNameIn(Collection<String> names);
|
||||||
|
|
||||||
|
List<Book> findByNameNotIn(Collection<String> names);
|
||||||
|
|
||||||
|
List<Book> findByNameAndPrice(String name, Integer price);
|
||||||
|
|
||||||
|
List<Book> findByNameOrPrice(String name, Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPrice(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceBetween(Integer lower, Integer upper);
|
||||||
|
|
||||||
|
List<Book> findByPriceLessThan(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceLessThanEqual(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceGreaterThan(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceGreaterThanEqual(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceBefore(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByPriceAfter(Integer price);
|
||||||
|
|
||||||
|
List<Book> findByAvailableTrue();
|
||||||
|
|
||||||
|
List<Book> findByAvailableFalse();
|
||||||
|
|
||||||
|
List<Book> findByAvailableTrueOrderByNameDesc();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Book {
|
||||||
|
@Id private String id;
|
||||||
|
private String name;
|
||||||
|
private Integer price;
|
||||||
|
@Field(type = FieldType.Boolean) private boolean available;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(Integer price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAvailable() {
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailable(Boolean available) {
|
||||||
|
this.available = available;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user