mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-02 16: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
|
||||
|
||||
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]]
|
||||
== Query creation
|
||||
@ -29,12 +29,14 @@ The method name above will be translated into the following Elasticsearch json q
|
||||
|
||||
[source]
|
||||
----
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
]
|
||||
{
|
||||
"query": {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "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
|
||||
| Elasticsearch Query String| `And`
|
||||
| `findByNameAndPrice`
|
||||
| `{"bool" : {"must" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Or`
|
||||
| `findByNameOrPrice`
|
||||
| `{"bool" : {"should" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"should" : [
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Is`
|
||||
| `findByName`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : "?"}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Not`
|
||||
| `findByNameNot`
|
||||
| `{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must_not" : [
|
||||
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Between`
|
||||
| `findByPriceBetween`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}`
|
||||
| `{ "query" : {
|
||||
"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`
|
||||
| `findByPriceLessThan`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
| `findByPriceLessThanEqual`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"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`
|
||||
| `findByPriceGreaterThan`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Before`
|
||||
| `findByPriceBefore`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `After`
|
||||
| `findByPriceAfter`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Like`
|
||||
| `findByNameLike`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `StartingWith`
|
||||
| `findByNameStartingWith`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `EndingWith`
|
||||
| `findByNameEndingWith`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?","analyze_wildcard" : true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Contains/Containing`
|
||||
| `findByNameContaining`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?*","analyze_wildcard" : true}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "\*?*", "fields" : [ "name" ] }, "analyze_wildcard": true }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `In`
|
||||
| `findByNameIn(Collection<String>names)`
|
||||
| `{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
|
||||
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{"bool" : {"must" : [
|
||||
{"terms" : {"name" : ["?","?"]}}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `NotIn`
|
||||
| `findByNameNotIn(Collection<String>names)`
|
||||
| `{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
|
||||
{"name" : "?"}}}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{"bool" : {"must_not" : [
|
||||
{"terms" : {"name" : ["?","?"]}}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `Near`
|
||||
| `findByStoreNear`
|
||||
@ -129,16 +235,35 @@ A list of supported keywords for Elasticsearch is shown below.
|
||||
|
||||
| `True`
|
||||
| `findByAvailableTrue`
|
||||
| `{"bool" : {"must" : {"field" : {"available" : true}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `False`
|
||||
| `findByAvailableFalse`
|
||||
| `{"bool" : {"must" : {"field" : {"available" : false}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "false", "fields" : [ "available" ] } }
|
||||
]
|
||||
}
|
||||
}}`
|
||||
|
||||
| `OrderBy`
|
||||
| `findByAvailableTrueOrderByNameDesc`
|
||||
| `{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
|
||||
{"must" : {"field" : {"available" : true}}}}`
|
||||
| `{ "query" : {
|
||||
"bool" : {
|
||||
"must" : [
|
||||
{ "query_string" : { "query" : "true", "fields" : [ "available" ] } }
|
||||
]
|
||||
}
|
||||
}, "sort":[{"name":{"order":"desc"}}]
|
||||
}`
|
||||
|
||||
|===
|
||||
|
||||
[[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