mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-22 03:52:10 +00:00
Polishing.
This commit is contained in:
parent
1d6a1b0f2f
commit
fb9ccf7b44
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repository.query.parser;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||
@ -35,6 +33,9 @@ import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* ElasticsearchQueryCreator
|
||||
*
|
||||
@ -47,159 +48,159 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuery, CriteriaQuery> {
|
||||
|
||||
private final MappingContext<?, ElasticsearchPersistentProperty> context;
|
||||
private final MappingContext<?, ElasticsearchPersistentProperty> context;
|
||||
|
||||
public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
|
||||
MappingContext<?, ElasticsearchPersistentProperty> context) {
|
||||
super(tree, parameters);
|
||||
this.context = context;
|
||||
}
|
||||
public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
|
||||
MappingContext<?, ElasticsearchPersistentProperty> context) {
|
||||
super(tree, parameters);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public ElasticsearchQueryCreator(PartTree tree, MappingContext<?, ElasticsearchPersistentProperty> context) {
|
||||
super(tree);
|
||||
this.context = context;
|
||||
}
|
||||
public ElasticsearchQueryCreator(PartTree tree, MappingContext<?, ElasticsearchPersistentProperty> context) {
|
||||
super(tree);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CriteriaQuery create(Part part, Iterator<Object> iterator) {
|
||||
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context.getPersistentPropertyPath(
|
||||
part.getProperty());
|
||||
return new CriteriaQuery(from(part,
|
||||
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
|
||||
iterator));
|
||||
}
|
||||
@Override
|
||||
protected CriteriaQuery create(Part part, Iterator<Object> iterator) {
|
||||
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context.getPersistentPropertyPath(
|
||||
part.getProperty());
|
||||
return new CriteriaQuery(from(part,
|
||||
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
|
||||
iterator));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CriteriaQuery and(Part part, CriteriaQuery base, Iterator<Object> iterator) {
|
||||
if (base == null) {
|
||||
return create(part, iterator);
|
||||
}
|
||||
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context.getPersistentPropertyPath(
|
||||
part.getProperty());
|
||||
return base.addCriteria(from(part,
|
||||
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
|
||||
iterator));
|
||||
}
|
||||
@Override
|
||||
protected CriteriaQuery and(Part part, CriteriaQuery base, Iterator<Object> iterator) {
|
||||
if (base == null) {
|
||||
return create(part, iterator);
|
||||
}
|
||||
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context.getPersistentPropertyPath(
|
||||
part.getProperty());
|
||||
return base.addCriteria(from(part,
|
||||
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
|
||||
iterator));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CriteriaQuery or(CriteriaQuery base, CriteriaQuery query) {
|
||||
return new CriteriaQuery(base.getCriteria().or(query.getCriteria()));
|
||||
}
|
||||
@Override
|
||||
protected CriteriaQuery or(CriteriaQuery base, CriteriaQuery query) {
|
||||
return new CriteriaQuery(base.getCriteria().or(query.getCriteria()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) {
|
||||
@Override
|
||||
protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) {
|
||||
|
||||
if (query == null) {
|
||||
// this is the case in a findAllByOrderByField method, add empty criteria
|
||||
query = new CriteriaQuery(new Criteria());
|
||||
}
|
||||
return query.addSort(sort);
|
||||
}
|
||||
if (query == null) {
|
||||
// this is the case in a findAllByOrderByField method, add empty criteria
|
||||
query = new CriteriaQuery(new Criteria());
|
||||
}
|
||||
return query.addSort(sort);
|
||||
}
|
||||
|
||||
private Criteria from(Part part, Criteria criteria, Iterator<?> parameters) {
|
||||
private Criteria from(Part part, Criteria criteria, Iterator<?> parameters) {
|
||||
|
||||
Part.Type type = part.getType();
|
||||
Part.Type type = part.getType();
|
||||
|
||||
return switch (type) {
|
||||
case TRUE -> criteria.is(true);
|
||||
case FALSE -> criteria.is(false);
|
||||
case NEGATING_SIMPLE_PROPERTY -> criteria.is(parameters.next()).not();
|
||||
case REGEX -> criteria.expression(parameters.next().toString());
|
||||
case LIKE, STARTING_WITH -> criteria.startsWith(parameters.next().toString());
|
||||
case ENDING_WITH -> criteria.endsWith(parameters.next().toString());
|
||||
case CONTAINING -> criteria.contains(parameters.next().toString());
|
||||
case GREATER_THAN -> criteria.greaterThan(parameters.next());
|
||||
case AFTER, GREATER_THAN_EQUAL -> criteria.greaterThanEqual(parameters.next());
|
||||
case LESS_THAN -> criteria.lessThan(parameters.next());
|
||||
case BEFORE, LESS_THAN_EQUAL -> criteria.lessThanEqual(parameters.next());
|
||||
case BETWEEN -> criteria.between(parameters.next(), parameters.next());
|
||||
case IN -> criteria.in(asArray(parameters.next()));
|
||||
case NOT_IN -> criteria.notIn(asArray(parameters.next()));
|
||||
case SIMPLE_PROPERTY, WITHIN -> this.within(part, criteria, parameters);
|
||||
case NEAR -> this.near(criteria, parameters);
|
||||
case EXISTS, IS_NOT_NULL -> criteria.exists();
|
||||
case IS_NULL -> criteria.not().exists();
|
||||
case IS_EMPTY -> criteria.empty();
|
||||
case IS_NOT_EMPTY -> criteria.notEmpty();
|
||||
default -> throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
|
||||
};
|
||||
}
|
||||
return switch (type) {
|
||||
case TRUE -> criteria.is(true);
|
||||
case FALSE -> criteria.is(false);
|
||||
case NEGATING_SIMPLE_PROPERTY -> criteria.is(parameters.next()).not();
|
||||
case REGEX -> criteria.expression(parameters.next().toString());
|
||||
case LIKE, STARTING_WITH -> criteria.startsWith(parameters.next().toString());
|
||||
case ENDING_WITH -> criteria.endsWith(parameters.next().toString());
|
||||
case CONTAINING -> criteria.contains(parameters.next().toString());
|
||||
case GREATER_THAN -> criteria.greaterThan(parameters.next());
|
||||
case AFTER, GREATER_THAN_EQUAL -> criteria.greaterThanEqual(parameters.next());
|
||||
case LESS_THAN -> criteria.lessThan(parameters.next());
|
||||
case BEFORE, LESS_THAN_EQUAL -> criteria.lessThanEqual(parameters.next());
|
||||
case BETWEEN -> criteria.between(parameters.next(), parameters.next());
|
||||
case IN -> criteria.in(asArray(parameters.next()));
|
||||
case NOT_IN -> criteria.notIn(asArray(parameters.next()));
|
||||
case SIMPLE_PROPERTY, WITHIN -> within(part, criteria, parameters);
|
||||
case NEAR -> near(criteria, parameters);
|
||||
case EXISTS, IS_NOT_NULL -> criteria.exists();
|
||||
case IS_NULL -> criteria.not().exists();
|
||||
case IS_EMPTY -> criteria.empty();
|
||||
case IS_NOT_EMPTY -> criteria.notEmpty();
|
||||
default -> throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
|
||||
};
|
||||
}
|
||||
|
||||
private Criteria within(Part part, Criteria criteria, Iterator<?> parameters) {
|
||||
private Criteria within(Part part, Criteria criteria, Iterator<?> parameters) {
|
||||
|
||||
Object firstParameter = parameters.next();
|
||||
Object secondParameter;
|
||||
Object firstParameter = parameters.next();
|
||||
Object secondParameter;
|
||||
|
||||
if (part.getType() == Part.Type.SIMPLE_PROPERTY) {
|
||||
if (part.getProperty().getType() != GeoPoint.class) {
|
||||
if (firstParameter != null) {
|
||||
return criteria.is(firstParameter);
|
||||
} else {
|
||||
// searching for null is a must_not (exists)
|
||||
return criteria.exists().not();
|
||||
}
|
||||
} else {
|
||||
// it means it's a simple find with exact geopoint matching (e.g. findByLocation)
|
||||
// and because Elasticsearch does not have any kind of query with just a geopoint
|
||||
// as argument we use a "geo distance" query with a distance of one meter.
|
||||
secondParameter = ".001km";
|
||||
}
|
||||
} else {
|
||||
secondParameter = parameters.next();
|
||||
}
|
||||
if (part.getType() == Part.Type.SIMPLE_PROPERTY) {
|
||||
if (part.getProperty().getType() != GeoPoint.class) {
|
||||
if (firstParameter != null) {
|
||||
return criteria.is(firstParameter);
|
||||
} else {
|
||||
// searching for null is a must_not (exists)
|
||||
return criteria.exists().not();
|
||||
}
|
||||
} else {
|
||||
// it means it's a simple find with exact geopoint matching (e.g. findByLocation)
|
||||
// and because Elasticsearch does not have any kind of query with just a geopoint
|
||||
// as argument we use a "geo distance" query with a distance of one meter.
|
||||
secondParameter = ".001km";
|
||||
}
|
||||
} else {
|
||||
secondParameter = parameters.next();
|
||||
}
|
||||
|
||||
return doWithinIfPossible(criteria, firstParameter, secondParameter);
|
||||
}
|
||||
return doWithinIfPossible(criteria, firstParameter, secondParameter);
|
||||
}
|
||||
|
||||
private Criteria near(Criteria criteria, Iterator<?> parameters) {
|
||||
private Criteria near(Criteria criteria, Iterator<?> parameters) {
|
||||
|
||||
Object firstParameter = parameters.next();
|
||||
Object firstParameter = parameters.next();
|
||||
|
||||
if (firstParameter instanceof GeoBox geoBox) {
|
||||
return criteria.boundedBy(geoBox);
|
||||
}
|
||||
if (firstParameter instanceof GeoBox geoBox) {
|
||||
return criteria.boundedBy(geoBox);
|
||||
}
|
||||
|
||||
if (firstParameter instanceof Box box) {
|
||||
return criteria.boundedBy(GeoBox.fromBox(box));
|
||||
}
|
||||
if (firstParameter instanceof Box box) {
|
||||
return criteria.boundedBy(GeoBox.fromBox(box));
|
||||
}
|
||||
|
||||
Object secondParameter = parameters.next();
|
||||
Object secondParameter = parameters.next();
|
||||
|
||||
return doWithinIfPossible(criteria, firstParameter, secondParameter);
|
||||
}
|
||||
return doWithinIfPossible(criteria, firstParameter, secondParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a within query if possible, otherwise return the criteria unchanged.
|
||||
*
|
||||
* @param criteria must not be {@literal null}
|
||||
* @param firstParameter must not be {@literal null}
|
||||
* @param secondParameter must not be {@literal null}
|
||||
* @return the criteria with the within query applied if possible.
|
||||
* @author Junghoon Ban
|
||||
*/
|
||||
private Criteria doWithinIfPossible(Criteria criteria, Object firstParameter, Object secondParameter) {
|
||||
/**
|
||||
* Do a within query if possible, otherwise return the criteria unchanged.
|
||||
*
|
||||
* @param criteria must not be {@literal null}
|
||||
* @param firstParameter must not be {@literal null}
|
||||
* @param secondParameter must not be {@literal null}
|
||||
* @return the criteria with the within query applied if possible.
|
||||
* @author Junghoon Ban
|
||||
*/
|
||||
private Criteria doWithinIfPossible(Criteria criteria, Object firstParameter, Object secondParameter) {
|
||||
|
||||
if (firstParameter instanceof GeoPoint geoPoint && secondParameter instanceof String string) {
|
||||
return criteria.within(geoPoint, string);
|
||||
}
|
||||
if (firstParameter instanceof GeoPoint geoPoint && secondParameter instanceof String string) {
|
||||
return criteria.within(geoPoint, string);
|
||||
}
|
||||
|
||||
if (firstParameter instanceof Point point && secondParameter instanceof Distance distance) {
|
||||
return criteria.within(point, distance);
|
||||
}
|
||||
if (firstParameter instanceof Point point && secondParameter instanceof Distance distance) {
|
||||
return criteria.within(point, distance);
|
||||
}
|
||||
|
||||
if (firstParameter instanceof String firstString && secondParameter instanceof String secondString) {
|
||||
return criteria.within(firstString, secondString);
|
||||
}
|
||||
if (firstParameter instanceof String firstString && secondParameter instanceof String secondString) {
|
||||
return criteria.within(firstString, secondString);
|
||||
}
|
||||
|
||||
return criteria;
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
private Object[] asArray(Object o) {
|
||||
if (o instanceof Collection) {
|
||||
return ((Collection<?>) o).toArray();
|
||||
} else if (o.getClass().isArray()) {
|
||||
return (Object[]) o;
|
||||
}
|
||||
return new Object[] { o };
|
||||
}
|
||||
private Object[] asArray(Object o) {
|
||||
if (o instanceof Collection) {
|
||||
return ((Collection<?>) o).toArray();
|
||||
} else if (o.getClass().isArray()) {
|
||||
return (Object[]) o;
|
||||
}
|
||||
return new Object[]{o};
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user