Spring-Data search API augmented with Natural Language support.
Demo:
spring-boot-starter-data-search-mongodb-demo
spring-boot-starter-data-search-jpa-demo
Data Search provides an enterprise & production ready API, prowered by Spring Boot and Antlr, to query your data, and perform advanced search with Natural Language.
Search example: users born after 1988-01-01, with an gmail or protonmail email address, having completed the email verification, and having an address in one of the following countries: France, Switzerland or China
birthDate >: '1988-01-01' and (emailAddress : *gmail.com or emailAddress: *protonmail.com) and emailAddressVerified: true and addresses.countryCode: 'FR,CH,CN'
- Logical operators (or/ and)
- Parenthesis/ criteria prioritization
- Mongodb and all JPA compatible db engines
- Fields mapping/ DTO to Entities
- Filter by subentity fields/ deep search
- Advanced RegEx for Mongodb and like operator for JPA
- All comparison operators
emailAddressVerified : true
emailAddressVerified !: true
countryCode : 'FR,CH,CN'
countryCode !: 'FR,CH,CN'
firstName: S*
firstName: *S
firstName: *S*
birthDate < '1988-01-01'
birthDate <: '1988-01-01'
birthDate > '1988-01-01'
birthDate >: '1988-01-01'
birthDate
!birthDate
firstName : Stan
emailAddressVerified : true
ref >: 100 or coins > 6.76453
time >: '18:58:24' and time <: '18:58:24.999'
time >: '18:58:24Z' and time <: '20:58:24.999+02:00'
birthDate >: '1988-01-01'
createdDate >: '2021-08-23T18:58:24' and createdDate <: '2021-10-12T18:58:24.000'
createdDate >: "2021-08-23T18:58:24Z" and createdDate <: '2021-10-12T18:58:24.000+02:00'
countryCode : 'FR,CH,CN'
emailAddress : '/.*gmail.com/'
Regular expression, supported only for mongodb (see documentation) |
See detailed search use case here
Java version 11 or higher (If java 8 support is needed, please vote for this issue)
SpringBoot version 2.1.0 or higher
https://github.com/commerce-io/spring-boot-starter-data-search-mongodb-demo
https://github.com/commerce-io/spring-boot-starter-data-search-jpa-demo
Maven
<dependency>
<groupId>app.commerce-io</groupId>
<artifactId>spring-boot-starter-data-search-mongodb</artifactId>
<version>1.2.0</version>
</dependency>
Gradle
implementation 'app.commerce-io:spring-boot-starter-data-search-mongodb:1.2.0'
Maven
<dependency>
<groupId>app.commerce-io</groupId>
<artifactId>spring-boot-starter-data-search-jpa</artifactId>
<version>1.2.0</version>
</dependency>
Gradle
implementation 'app.commerce-io:spring-boot-starter-data-search-jpa:1.2.0'
Data Search provides a custom repository. In order to use the provided repository, add the following annotation to the main class or any other configuration class.
@Configuration
@EnableMongoRepositories(repositoryBaseClass = SearchRepositoryImpl.class)
public class DemoConfiguration {
}
@Configuration
@EnableJpaRepositories(repositoryBaseClass = SearchRepositoryImpl.class)
public class DemoConfiguration {
}
Make your repositories extend SearchRepository
@Repository
public interface CustomerRepository extends SearchRepository<Customer, String> {
}
And use in a controller or from anywhere else
@RestController
@RequiredArgsConstructor
public class DemoController {
private final CustomerRepository customerRepository;
@Transactional(readOnly = true)
@RequestMapping(
method = RequestMethod.GET,
value = "/customers",
produces = {"application/json"}
)
public ResponseEntity<Page<Customer>> searchCustomers(
@RequestParam(value = "search", required = false) String search,
Pageable pageable) {
Page<Customer> customerPage = customerRepository.findAll(
search,
pageable);
return ok(customerPage);
}
}
Users will tend to filter by the search result fields, and sometimes, your DTO structure differs from your entity/ collection. Data search provides a mapper, to define your custom mappings rules in two different ways:
The flat mapper is a basic String to String mapping, which could be useful for simple use cases.
String search = "addressName: test";
Mapper addressMapper = Mapper.flatMapper()
.mapping("addressName", "address.firstName")
.build();
Page<CustomerEntity> page = customerRepository.findAll(search, pageable, addressMapper);
The advanced mapper is used for complex structure mapping, and enable the reuse of mappers. Advanced mappers can be combined with flat mappers.
String search = "name: test OR address.addressName: test";
Mapper addressMapper = Mapper.flatMapper()
.mapping("addressName", "firstName")
.build();
Mapper mapper = Mapper.mapper()
.mapping("name", "firstName")
.mapping("address", "addressEntity", addressMapper)
.build();
Page<CustomerEntity> page = customerRepository.findAll(search, pageable, mapper);
In addition to the fields mapping, some values could be converted before returning the search result, like returning labels instead of codes in some scenarios.
We recently (in the 1.2.0) added the value mapping feature to Spring Data Search, to be used as follows:
public class LowerCaseValueMapping implements ValueMapping {
@Override
public String map(String from) {
return from == null ? null : from.toLowerCase();
}
}
String search = "addressName: TeSt";
Mapper addressMapper = Mapper.flatMapper()
.mapping("addressName", "address.firstName", new LowerCaseValueMapping())
.build();
Page<CustomerEntity> page = customerRepository.findAll(search, pageable, addressMapper);
This software is released under the Apache license. See LICENSE
for more information.