15
15
*/
16
16
package org .springframework .data .mongodb .repository .query ;
17
17
18
- import static org .springframework .data .mongodb .repository .query .QueryUtils .applyPagination ;
18
+ import static org .springframework .data .mongodb .repository .query .QueryUtils .* ;
19
19
20
20
import java .util .List ;
21
21
22
22
import org .springframework .data .domain .PageImpl ;
23
23
import org .springframework .data .domain .Pageable ;
24
- import org .springframework .data .mongodb .core .CollectionCallback ;
25
24
import org .springframework .data .mongodb .core .MongoOperations ;
26
25
import org .springframework .data .mongodb .core .geo .Distance ;
26
+ import org .springframework .data .mongodb .core .geo .GeoPage ;
27
27
import org .springframework .data .mongodb .core .geo .GeoResult ;
28
28
import org .springframework .data .mongodb .core .geo .GeoResults ;
29
29
import org .springframework .data .mongodb .core .geo .Point ;
34
34
import org .springframework .data .util .TypeInformation ;
35
35
import org .springframework .util .Assert ;
36
36
37
- import com .mongodb .DBCollection ;
38
- import com .mongodb .DBCursor ;
39
- import com .mongodb .DBObject ;
40
-
41
37
/**
42
38
* Base class for {@link RepositoryQuery} implementations for Mongo.
43
39
*
@@ -51,8 +47,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
51
47
/**
52
48
* Creates a new {@link AbstractMongoQuery} from the given {@link MongoQueryMethod} and {@link MongoOperations}.
53
49
*
54
- * @param method
55
- * @param template
50
+ * @param method must not be {@literal null}.
51
+ * @param template must not be {@literal null}.
56
52
*/
57
53
public AbstractMongoQuery (MongoQueryMethod method , MongoOperations template ) {
58
54
@@ -63,25 +59,30 @@ public AbstractMongoQuery(MongoQueryMethod method, MongoOperations template) {
63
59
this .mongoOperations = template ;
64
60
}
65
61
66
- /* (non-Javadoc)
62
+ /*
63
+ * (non-Javadoc)
67
64
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
68
65
*/
69
66
public MongoQueryMethod getQueryMethod () {
70
-
71
67
return method ;
72
68
}
73
69
74
70
/*
75
- * (non-Javadoc)
76
- *
77
- * @see org.springframework.data.repository.query.RepositoryQuery#execute(java .lang.Object[])
78
- */
71
+ * (non-Javadoc)
72
+ * @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
73
+ */
79
74
public Object execute (Object [] parameters ) {
80
75
81
76
MongoParameterAccessor accessor = new MongoParametersParameterAccessor (method , parameters );
82
77
Query query = createQuery (new ConvertingParameterAccessor (mongoOperations .getConverter (), accessor ));
83
78
84
- if (method .isGeoNearQuery ()) {
79
+ if (method .isGeoNearQuery () && method .isPageQuery ()) {
80
+
81
+ MongoParameterAccessor countAccessor = new MongoParametersParameterAccessor (method , parameters );
82
+ Query countQuery = createCountQuery (new ConvertingParameterAccessor (mongoOperations .getConverter (), countAccessor ));
83
+
84
+ return new GeoNearExecution (accessor ).execute (query , countQuery );
85
+ } else if (method .isGeoNearQuery ()) {
85
86
return new GeoNearExecution (accessor ).execute (query );
86
87
} else if (method .isCollectionQuery ()) {
87
88
return new CollectionExecution ().execute (query );
@@ -93,14 +94,25 @@ public Object execute(Object[] parameters) {
93
94
}
94
95
95
96
/**
96
- * Create a {@link Query} instance using the given {@link ParameterAccessor}
97
+ * Creates a {@link Query} instance using the given {@link ParameterAccessor}
97
98
*
98
- * @param accessor
99
- * @param converter
99
+ * @param accessor must not be {@literal null}.
100
100
* @return
101
101
*/
102
102
protected abstract Query createQuery (ConvertingParameterAccessor accessor );
103
103
104
+ /**
105
+ * Creates a {@link Query} instance using the given {@link ConvertingParameterAccessor}. Will delegate to
106
+ * {@link #createQuery(ConvertingParameterAccessor)} by default but allows customization of the count query to be
107
+ * triggered.
108
+ *
109
+ * @param accessor must not be {@literal null}.
110
+ * @return
111
+ */
112
+ protected Query createCountQuery (ConvertingParameterAccessor accessor ) {
113
+ return createQuery (accessor );
114
+ }
115
+
104
116
private abstract class Execution {
105
117
106
118
abstract Object execute (Query query );
@@ -122,13 +134,11 @@ protected List<?> readCollection(Query query) {
122
134
class CollectionExecution extends Execution {
123
135
124
136
/*
125
- * (non-Javadoc)
126
- *
127
- * @see org.springframework.data.mongodb.repository.MongoQuery.Execution #execute(com.mongodb.DBObject)
128
- */
137
+ * (non-Javadoc)
138
+ * @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
139
+ */
129
140
@ Override
130
141
public Object execute (Query query ) {
131
-
132
142
return readCollection (query );
133
143
}
134
144
}
@@ -162,24 +172,13 @@ public PagedExecution(Pageable pageable) {
162
172
Object execute (Query query ) {
163
173
164
174
MongoEntityInformation <?, ?> metadata = method .getEntityInformation ();
165
- int count = getCollectionCursor ( metadata . getCollectionName (), query . getQueryObject ()). count ( );
175
+ long count = mongoOperations . count ( query , metadata . getCollectionName () );
166
176
167
177
List <?> result = mongoOperations .find (applyPagination (query , pageable ), metadata .getJavaType (),
168
178
metadata .getCollectionName ());
169
179
170
180
return new PageImpl (result , pageable , count );
171
181
}
172
-
173
- private DBCursor getCollectionCursor (String collectionName , final DBObject query ) {
174
-
175
- return mongoOperations .execute (collectionName , new CollectionCallback <DBCursor >() {
176
-
177
- public DBCursor doInCollection (DBCollection collection ) {
178
-
179
- return collection .find (query );
180
- }
181
- });
182
- }
183
182
}
184
183
185
184
/**
@@ -221,6 +220,28 @@ public GeoNearExecution(MongoParameterAccessor accessor) {
221
220
@ Override
222
221
Object execute (Query query ) {
223
222
223
+ GeoResults <?> results = doExecuteQuery (query );
224
+ return isListOfGeoResult () ? results .getContent () : results ;
225
+ }
226
+
227
+ /**
228
+ * Executes the given {@link Query} to return a page.
229
+ *
230
+ * @param query must not be {@literal null}.
231
+ * @param countQuery must not be {@literal null}.
232
+ * @return
233
+ */
234
+ Object execute (Query query , Query countQuery ) {
235
+
236
+ MongoEntityInformation <?, ?> information = method .getEntityInformation ();
237
+ long count = mongoOperations .count (countQuery , information .getCollectionName ());
238
+
239
+ return new GeoPage <Object >(doExecuteQuery (query ), accessor .getPageable (), count );
240
+ }
241
+
242
+ @ SuppressWarnings ("unchecked" )
243
+ private GeoResults <Object > doExecuteQuery (Query query ) {
244
+
224
245
Point nearLocation = accessor .getGeoNearLocation ();
225
246
NearQuery nearQuery = NearQuery .near (nearLocation );
226
247
@@ -234,10 +255,8 @@ Object execute(Query query) {
234
255
}
235
256
236
257
MongoEntityInformation <?, ?> entityInformation = method .getEntityInformation ();
237
- GeoResults <?> results = mongoOperations .geoNear (nearQuery , entityInformation .getJavaType (),
258
+ return ( GeoResults <Object >) mongoOperations .geoNear (nearQuery , entityInformation .getJavaType (),
238
259
entityInformation .getCollectionName ());
239
-
240
- return isListOfGeoResult () ? results .getContent () : results ;
241
260
}
242
261
243
262
private boolean isListOfGeoResult () {
0 commit comments