Skip to content

Commit 380ade4

Browse files
committed
Perform conversion from Query Where clause, to mongodb BSON queries....
Unfortunately, it means orderby is now broken somehow (to fix)
1 parent d5b8fb6 commit 380ade4

1 file changed

Lines changed: 164 additions & 6 deletions

File tree

src/main/java/picoded/dstack/mongodb/MongoDB_DataObjectMap.java

Lines changed: 164 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
import picoded.core.conv.NestedObjectFetch;
1818
import picoded.core.conv.NestedObjectUtil;
1919
import picoded.core.conv.StringEscape;
20+
import picoded.core.struct.query.OrderBy;
2021
import picoded.core.struct.query.Query;
22+
import picoded.core.struct.query.QueryType;
2123
import picoded.core.common.ObjectToken;
2224
import picoded.dstack.*;
2325
import picoded.dstack.core.*;
2426

2527
// MongoDB imports
2628
import org.bson.Document;
2729
import org.bson.types.Binary;
30+
import org.bson.conversions.Bson;
2831
import com.mongodb.client.*;
2932
import com.mongodb.client.model.Projections;
3033
import com.mongodb.client.model.Filters;
@@ -67,12 +70,6 @@ public MongoDB_DataObjectMap(MongoDBStack inStack, String name) {
6770
collection = inStack.db_conn.getCollection(name);
6871
}
6972

70-
//--------------------------------------------------------------------------
71-
//
72-
// BSON utilities
73-
//
74-
//--------------------------------------------------------------------------
75-
7673
//--------------------------------------------------------------------------
7774
//
7875
// Backend system setup / teardown (DStackCommon)
@@ -298,6 +295,167 @@ public Set<String> keySet() {
298295
return ret;
299296
}
300297

298+
//--------------------------------------------------------------------------
299+
//
300+
// Query based optimization
301+
//
302+
//--------------------------------------------------------------------------
303+
304+
/**
305+
* Given the SQL style query, convert it into the BSON query format
306+
*/
307+
static protected Bson queryObjToBsonFilter(Query inQuery) {
308+
QueryType type = inQuery.type();
309+
310+
// Handle the query according to its type
311+
if( inQuery.isCombinationOperator() ) {
312+
// Lets convert each of the subquery
313+
List<Bson> remappedQuery = new ArrayList<>();
314+
for( Query subQuery : inQuery.childrenQuery() ) {
315+
remappedQuery.add( queryObjToBsonFilter(subQuery) );
316+
}
317+
// Combination type (AND, OR, NOT)
318+
if( type == QueryType.AND ) {
319+
return Filters.and( remappedQuery );
320+
}
321+
if( type == QueryType.OR ) {
322+
return Filters.or( remappedQuery );
323+
}
324+
if( type == QueryType.NOT ) {
325+
if( remappedQuery.size() > 0 ) {
326+
throw new RuntimeException("NOT operator, expects only 1 subquery");
327+
}
328+
return Filters.not( remappedQuery.get(0) );
329+
}
330+
} else {
331+
// Basic operator
332+
if( type == QueryType.EQUALS ) {
333+
return Filters.eq( inQuery.fieldName(), inQuery.defaultArgumentValue() );
334+
}
335+
if( type == QueryType.NOT_EQUALS ) {
336+
return Filters.ne( inQuery.fieldName(), inQuery.defaultArgumentValue() );
337+
}
338+
if( type == QueryType.LESS_THAN ) {
339+
return Filters.lt( inQuery.fieldName(), inQuery.defaultArgumentValue() );
340+
}
341+
if( type == QueryType.LESS_THAN_OR_EQUALS ) {
342+
return Filters.lte( inQuery.fieldName(), inQuery.defaultArgumentValue() );
343+
}
344+
if( type == QueryType.MORE_THAN ) {
345+
return Filters.gt( inQuery.fieldName(), inQuery.defaultArgumentValue() );
346+
}
347+
if( type == QueryType.MORE_THAN_OR_EQUALS ) {
348+
return Filters.gte( inQuery.fieldName(), inQuery.defaultArgumentValue() );
349+
}
350+
if( type == QueryType.LIKE ) {
351+
// Because the LIKE operator does not natively exists,
352+
// we will generates its REGEX equivalent
353+
354+
String val = GenericConvert.toString( inQuery.defaultArgumentValue() );
355+
val = val.replaceAll("*","\\*");
356+
val = val.replaceAll("%",".*");
357+
val = val.replaceAll("_",".+");
358+
359+
return Filters.regex( inQuery.fieldName(), val );
360+
}
361+
}
362+
363+
throw new RuntimeException("Unkown query type : "+inQuery.type());
364+
}
365+
366+
/**
367+
* Performs a search query, and returns the respective DataObject keys.
368+
*
369+
* This is the GUID key varient of query, this is critical for stack lookup
370+
*
371+
* @param queryClause, of where query statement and value
372+
* @param orderByStr string to sort the order by, use null to ignore
373+
* @param offset of the result to display, use -1 to ignore
374+
* @param number of objects to return max, use -1 to ignore
375+
*
376+
* @return The String[] array
377+
**/
378+
public String[] query_id(Query queryClause, String orderByStr, int offset, int limit) {
379+
380+
// The query filter to use, use "all" if queryClause is null
381+
Bson bsonFilter = null;
382+
if( queryClause != null ) {
383+
// Lets convert the SQL where clause to bsonFilter
384+
bsonFilter = queryObjToBsonFilter(queryClause);
385+
} else {
386+
// our equivalent of all filter
387+
bsonFilter = Filters.exists("_oid", true);
388+
}
389+
390+
// Lets fetch the data, for the various _oid
391+
FindIterable<Document> search = collection.find(bsonFilter);
392+
search = search.projection(Projections.include("_oid"));
393+
394+
// Build the orderBy clause
395+
if( orderByStr != null && orderByStr.length() > 0 ) {
396+
// The final sorting BSON
397+
Document sortBson = new Document();
398+
399+
// Normalize it first
400+
orderByStr = (new OrderBy(orderByStr)).toString();
401+
402+
// Split it accordingly
403+
String[] orderSeq = orderByStr.split(",");
404+
for(int i=0; i<orderSeq.length; ++i) {
405+
String subSeq = orderSeq[i];
406+
407+
// This safely handles both ASC, and DESC sequence
408+
String field = subSeq.substring(0, subSeq.length()-4).trim();
409+
410+
// Append the order by rule accordingly
411+
if( subSeq.endsWith("ASC") ) {
412+
sortBson.append(field, 1);
413+
} else if( subSeq.endsWith("DESC") ) {
414+
sortBson.append(field, -1);
415+
}
416+
}
417+
418+
// Apply the sorting
419+
search.sort( sortBson );
420+
}
421+
422+
// Handle offset
423+
if( offset > 0 ) {
424+
search.skip(offset);
425+
}
426+
427+
// And length
428+
if( limit >= 0 ) {
429+
search.limit(limit);
430+
}
431+
432+
// The return list
433+
List<String> ret = new ArrayList<String>();
434+
435+
// Lets iterate the search
436+
try (MongoCursor<Document> cursor = search.iterator()) {
437+
while (cursor.hasNext()) {
438+
ret.add(cursor.next().getString("_oid"));
439+
}
440+
}
441+
442+
// Return the full keyset
443+
return GenericConvert.toStringArray(ret);
444+
}
445+
446+
// /**
447+
// * Performs a search query, and returns the respective DataObjects
448+
// *
449+
// * @param where query statement
450+
// * @param where clause values array
451+
// *
452+
// * @returns The total count for the query
453+
// */
454+
// @Override
455+
// public long queryCount(String whereClause, Object[] whereValues) {
456+
// return queryBuilder.dataObjectMapCount(whereClause, whereValues, null, -1, -1);
457+
// }
458+
301459
//--------------------------------------------------------------------------
302460
//
303461
// Maintenance calls

0 commit comments

Comments
 (0)