DATAES-129 : Custom Repository Method for simple geo request does not work

This commit is contained in:
Franck MARCHAND 2014-09-13 00:43:24 +02:00 committed by Mohsin Husen
parent 7cf7cb9168
commit bb62148bb7
5 changed files with 80 additions and 14 deletions

View File

@ -24,10 +24,10 @@ import java.util.List;
import java.util.ListIterator;
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostableQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.*;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
/**
@ -118,9 +118,9 @@ class CriteriaQueryProcessor {
}
QueryBuilder query = null;
String searchText = StringUtils.toString(value);
String searchText = StringUtils.toString(value);
switch (key) {
switch (key) {
case EQUALS:
query = queryString(searchText).field(fieldName);
break;

View File

@ -193,7 +193,7 @@ public class Criteria {
* @return
*/
public Criteria is(Object o) {
queryCriteria.add(new CriteriaEntry(OperationKey.EQUALS, o));
queryCriteria.add(new CriteriaEntry(OperationKey.EQUALS, o));
return this;
}

View File

@ -61,7 +61,7 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
protected CriteriaQuery create(Part part, Iterator<Object> iterator) {
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context
.getPersistentPropertyPath(part.getProperty());
return new CriteriaQuery(from(part.getType(),
return new CriteriaQuery(from(part,
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator));
}
@ -72,7 +72,7 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
}
PersistentPropertyPath<ElasticsearchPersistentProperty> path = context
.getPersistentPropertyPath(part.getProperty());
return base.addCriteria(from(part.getType(),
return base.addCriteria(from(part,
new Criteria(path.toDotPath(ElasticsearchPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator));
}
@ -89,7 +89,9 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
return query.addSort(sort);
}
private Criteria from(Part.Type type, Criteria instance, Iterator<?> parameters) {
private Criteria from(Part part, Criteria instance, Iterator<?> parameters) {
Part.Type type = part.getType();
Criteria criteria = instance;
if (criteria == null) {
criteria = new Criteria();
@ -99,8 +101,6 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
return criteria.is(true);
case FALSE:
return criteria.is(false);
case SIMPLE_PROPERTY:
return criteria.is(parameters.next());
case NEGATING_SIMPLE_PROPERTY:
return criteria.is(parameters.next()).not();
case REGEX:
@ -126,11 +126,24 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
return criteria.in(asArray(parameters.next()));
case NOT_IN:
return criteria.in(asArray(parameters.next())).not();
case SIMPLE_PROPERTY:
case WITHIN: {
Object firstParameter = parameters.next();
Object secondParameter = parameters.next();
Object secondParameter = null;
if(type == Part.Type.SIMPLE_PROPERTY) {
if(part.getProperty().getType() != GeoPoint.class)
return criteria.is(firstParameter);
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 (firstParameter instanceof GeoPoint && secondParameter instanceof String)
if (firstParameter instanceof GeoPoint && secondParameter instanceof String)
return criteria.within((GeoPoint) firstParameter, (String) secondParameter);
if (firstParameter instanceof Point && secondParameter instanceof Distance)

View File

@ -495,6 +495,55 @@ public class CustomMethodRepositoryTests {
assertThat(sampleEntities.size(), is(1));
}
@Test
public void shouldExecuteCustomMethodWithGeoPoint() {
// given
String documentId = randomNumeric(5);
SampleEntity sampleEntity = new SampleEntity();
sampleEntity.setId(documentId);
sampleEntity.setType("test");
sampleEntity.setRate(10);
sampleEntity.setMessage("foo");
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
repository.save(sampleEntity);
// when
Page<SampleEntity> page = repository.findByLocation(new GeoPoint(45.7806d, 3.0875d), new PageRequest(0, 10));
// then
assertThat(page, is(notNullValue()));
assertThat(page.getTotalElements(), is(equalTo(1L)));
}
@Test
public void shouldExecuteCustomMethodWithGeoPointAndString() {
// given
String documentId = randomNumeric(5);
SampleEntity sampleEntity = new SampleEntity();
sampleEntity.setId(documentId);
sampleEntity.setType("test");
sampleEntity.setRate(10);
sampleEntity.setMessage("foo");
sampleEntity.setLocation(new GeoPoint(45.7806d, 3.0875d));
repository.save(sampleEntity);
documentId = randomNumeric(5);
sampleEntity = new SampleEntity();
sampleEntity.setId(documentId);
sampleEntity.setType("test");
sampleEntity.setRate(10);
sampleEntity.setMessage("foo");
sampleEntity.setLocation(new GeoPoint(48.7806d, 3.0875d));
repository.save(sampleEntity);
// when
Page<SampleEntity> page = repository.findByLocationAndMessage(new GeoPoint(45.7806d, 3.0875d), "foo", new PageRequest(0, 10));
// then
assertThat(page, is(notNullValue()));
assertThat(page.getTotalElements(), is(equalTo(1L)));
}
@Test
public void shouldExecuteCustomMethodWithWithinGeoPoint() {
// given

View File

@ -71,7 +71,11 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository<Sa
Page<SampleEntity> findByMessageOrderByTypeAsc(String message, Pageable pageable);
Page<SampleEntity> findByLocationWithin(GeoPoint point, String distance, Pageable pageable);
Page<SampleEntity> findByLocation(GeoPoint point, Pageable pageable);
Page<SampleEntity> findByLocationAndMessage(GeoPoint point, String msg, Pageable pageable);
Page<SampleEntity> findByLocationWithin(GeoPoint point, String distance, Pageable pageable);
Page<SampleEntity> findByLocationWithin(Point point, Distance distance, Pageable pageable);