kobee1203 / weedow-searchy Goto Github PK
View Code? Open in Web Editor NEWAutomatically exposes web services over HTTP to search for Entity-related data using a powerful query language
License: MIT License
Automatically exposes web services over HTTP to search for Entity-related data using a powerful query language
License: MIT License
The default search endpoint is /search/{searchDescriptorId}
.
Allow to customize this root URI /search
.
Define a property spring.data.search.endpoint
with default value /search
.
Allow to override this property to customize the URI.
Find a solution to use this property in the Controller.
Let's say, we have the following Person entity:
@Document
public class Person {
//...//
@DBRef
private Job jobEntity;
@DBRef(lazy = true)
private Set<Vehicle> vehicles;
@DBRef(lazy = true)
private Map<Task, TaskTime> tasks;
//...//
}
We cannot search for fields annotated with @DBRef
Example of query:
/search/person?query=vehicles.brand='Renault' AND job.company='Acme'
Update the MongoQueryBuilder.join method to manage Entity joins
Create a new module 'mongodb' to support MongoDB.
Add a new sample app with MongoDB.
There are multiple sample apps and there will be others when there will be other database implementations.
To avoid polluting the root directory, group all sample apps into a 'samples' directory.
Update pom.xml parent to replace sample-app module by 'samples' module.
Add a pom.xml in samples directory with a tag referencing the sample apps
Update the distribution module: update assembly.xml with new 'target' paths
Allow to use CURRENT_DATE
, CURRENT_TIME
, CURRENT_DATE_TIME
in the query to compare a field with the current date/time.
Examples:
expiredOn<CURRENT_DATE
: Find all contracts expired before the current daynextUpdateTime<=CURRENT_TIME
: Find all contracts to be updated by comparing nextUpdateTime
with the current timeexpiredOn<=CURRENT_DATE_TIME
: Find all contracts expired on the current date and time or beforeThis improvement requires to update ExpressionResolverImpl
, to check the keywords during conversion.
class ExpressionResolverImpl(
private val fieldPathResolver: FieldPathResolver,
private val conversionService: ConversionService
) : ExpressionResolver {
...
private fun convert(value: String, clazz: Class<*>): Any {
return when {
CurrentDate.CURRENT_DATE.equals(value, ignoreCase = true) -> CurrentDate
CurrentTime.CURRENT_TIME.equals(value, ignoreCase = true) -> CurrentTime
CurrentDateTime.CURRENT_DATE_TIME.equals(value, ignoreCase = true) -> CurrentDateTime
NullValue.NULL_VALUE.equals(value, ignoreCase = true) -> NullValue
else -> conversionService.convert(value, clazz)!!
}
}
}
Then, update SimpleExpression
to check the keywords, and convert the value to an Expression
.
internal data class SimpleExpression(
private val operator: Operator,
private val fieldInfo: FieldInfo,
private val value: Any
) : Expression {
...
private fun equals(criteriaBuilder: CriteriaBuilder, path: Path<*>, value: Any, fieldInfo: FieldInfo): Predicate {
val field = fieldInfo.parentClass.getDeclaredField(fieldInfo.fieldName)
return if (value === NullValue) {
...
} else {
if (EntityUtils.isElementCollection(field)) {
...
} else {
val expression = convertValueToExpression(criteriaBuilder, value)
criteriaBuilder.equal(path, expression)
}
}
}
...
private fun <Y : Comparable<Y>> lessThan(criteriaBuilder: CriteriaBuilder, path: Path<Y>, value: Y): Predicate {
val expression = convertValueToExpression(criteriaBuilder, value)
return criteriaBuilder.lessThan(path, expression)
}
private fun <Y : Comparable<Y>> lessThanOrEquals(criteriaBuilder: CriteriaBuilder, path: Path<Y>, value: Y): Predicate {
val expression = convertValueToExpression(criteriaBuilder, value)
return criteriaBuilder.lessThanOrEqualTo(path, expression)
}
private fun <Y : Comparable<Y>> greaterThan(criteriaBuilder: CriteriaBuilder, path: Path<Y>, value: Y): Predicate {
val expression = convertValueToExpression(criteriaBuilder, value)
return criteriaBuilder.greaterThan(path, expression)
}
private fun <Y : Comparable<Y>> greaterThanOrEquals(criteriaBuilder: CriteriaBuilder, path: Path<Y>, value: Y): Predicate {
val expression = convertValueToExpression(criteriaBuilder, value)
return criteriaBuilder.greaterThanOrEqualTo(path, expression)
}
...
private fun convertValueToExpression(criteriaBuilder: CriteriaBuilder, value: Any): javax.persistence.criteria.Expression<*> {
return when {
CurrentDate === value -> criteriaBuilder.currentDate()
CurrentTime === value -> criteriaBuilder.currentTime()
CurrentDateTime === value -> criteriaBuilder.currentTimestamp()
else -> criteriaBuilder.literal(value)
}
}
}
Other improvement: Group all keywords CURRENT_DATE
, CURRENT_TIME
, CURRENT_DATE_TIME
and NULL_VALUE
in the same constant class Keyword
Documentate the new keywords in README.md
map_contains_value.js
is used to handle Entity fields from Map value
Example:
class Person {
private Address mainAddress;
...
}
class Address {
private Map<String, RoomDescription> roomDescription;
...
}
class RoomDescription {
private Double area;
private String floor;
private Integer windows;
private RoomType type;
}
Example of query with equals
operator:
/search/person?query=mainAddress.roomDescription.value.type='OFFICE'
But we cannot search for other operators
/search/person?query=mainAddress.roomDescription.value.area>20 AND mainAddress.roomDescription.value.area<30
/search/person?query=mainAddress.roomDescription.value.floor LIKE '*first*'
/search/person?query=mainAddress.roomDescription.value.floor ILIKE '*FIRST*'
...
Update the map_contains_value.js
file to handle other operators:
function() {
...
var deepIterate = function (obj, path, value, op) {
...
var check = function(obj, value, op) {
if(op == '=') {
return obj == value;
} else if(op == '<') {
return obj < value;
}
...
}
return deepIterate(this, "{PATH}", {VALUE}, {OP});
}
Update MongoQueryBuilder
to use map_contains_value.js
for other operators
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.