Как уже упоминалось в комментариях, вы ищете нечеткий поиск. Это не то, что вы можете легко сделать в базе данных, но есть отдельные поисковые системы, которые вы можете использовать:
- Apache Solr (платформа на основе Apache Lucene)
- ElasticSearch
- Hibernate Search (интеграция Hibernate с Apache Lucene)
- ...
При использовании такого решения вам придется также индексировать свои объекты в поисковой системе. Spring Data может помочь вам в этом, поскольку есть также библиотека для Solr .
Прежде всего вам нужен новый класс, который представляет, как ваша сущность будет выглядеть в Solr. Помните, что вы хотите «сплющить» все, если бы у вас были вложенные отношения:
@Document
public class UserDocument {
@Id
@Indexed("id")
private String id;
@Indexed("firstName")
private String firstName;
@Indexed("lastName")
private String lastName;
@Indexed("userName")
private String userName;
// ...
}
После этого вы можете написать репозиторий, как вы привыкли к Spring Data:
public interface UserDocumentRepository extends SolrCrudRepository<UserDocument, String> {
@Query("userName:?0 OR firstName:?0 OR lastName:?0")
List<UserDocument> findAll(String searchTerm);
}
После этого вы можете сделать что-то вроде этого:
public User create(User input) {
// Create user in database
documentRepository.save(new UserDocument(input.getFirstName(), input.getLastName(), input.getUserName());
}
И вы можете запросить нечеткие поиски, используя также хранилище:
documentRepository.findAll("vickz~3");
Это будет использовать запрос, который я только что написал, и будет искать имена, фамилии или имена пользователей, содержащие vickz. ~3
в конце - специальный синтаксис , указывающий, что имя может содержать 3 символа, отличных от того, который я только что использовал (= расстояние редактирования).
Однако это вернет UserDocument
сущности Solr. Если вы хотите получить сущности, вам также нужно их найти, что можно сделать по их имени пользователя:
List<String> usernames = documentRepository
.findAll("vickz~3")
.stream()
.map(UserDocument::getUserName)
.collect(Collectors.toList());
repository.findByUsername(usernames); // Look in database for users matching those usernames