Better fulltext search
This commit is contained in:
parent
7970c16026
commit
83aacd2a8d
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import {getBaseUrl} from "./UrlHelper";
|
import {getBaseUrl} from "./UrlHelper";
|
||||||
|
|
||||||
const PROD: boolean = true;
|
const PROD: boolean = false;
|
||||||
|
|
||||||
export const environment = {
|
export const environment = {
|
||||||
production: false,
|
production: false,
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
package de.ph87.homeautomation;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import javax.persistence.criteria.Expression;
|
||||||
|
import javax.persistence.criteria.Predicate;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class RepositorySearchHelper {
|
||||||
|
|
||||||
|
public static <T, D> List<D> search(final String term, final JpaSpecificationExecutor<T> repository, final String fieldName, final Function<T, D> map) {
|
||||||
|
final Specification<T> specification = (root, query, criteriaBuilder) -> {
|
||||||
|
final Expression<String> field = criteriaBuilder.lower(root.get(fieldName));
|
||||||
|
final String term2 = term
|
||||||
|
.replaceAll("([a-zA-Z])([0-9])", "$1 $2")
|
||||||
|
.replaceAll("([0-9])([a-zA-Z])", "$1 $2")
|
||||||
|
.replaceAll("([A-Z])([A-Z])", "$1 $2")
|
||||||
|
.replaceAll("([a-z])([A-Z])", "$1 $2")
|
||||||
|
.toLowerCase(Locale.ROOT);
|
||||||
|
System.out.println(term2);
|
||||||
|
final List<Predicate> predicates = Arrays.stream(term2.split("\\s"))
|
||||||
|
.filter(word -> !word.isEmpty())
|
||||||
|
.map(word -> criteriaBuilder.like(field, "%" + word + "%"))
|
||||||
|
.toList();
|
||||||
|
return criteriaBuilder.and(predicates.toArray(Predicate[]::new));
|
||||||
|
};
|
||||||
|
final PageRequest pageRequest = PageRequest.of(0, 20, Sort.by(Sort.Direction.ASC, fieldName));
|
||||||
|
return repository.findAll(specification, pageRequest).stream().map(map).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -63,7 +63,7 @@ public class BulkController implements ISearchController {
|
|||||||
@PostMapping("searchLike")
|
@PostMapping("searchLike")
|
||||||
@Deprecated(since = "Use 'filter' instead", forRemoval = true)
|
@Deprecated(since = "Use 'filter' instead", forRemoval = true)
|
||||||
public List<SearchResult> searchLike(@RequestBody final String term) {
|
public List<SearchResult> searchLike(@RequestBody final String term) {
|
||||||
return bulkReader.findAllDtoLike("%" + term + "%").stream().map(this::toSearchResult).toList();
|
return bulkReader.search(term).stream().map(this::toSearchResult).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("findAll")
|
@GetMapping("findAll")
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.bulk;
|
package de.ph87.homeautomation.bulk;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.RepositorySearchHelper;
|
||||||
import de.ph87.homeautomation.property.Property;
|
import de.ph87.homeautomation.property.Property;
|
||||||
import de.ph87.homeautomation.web.NotFoundException;
|
import de.ph87.homeautomation.web.NotFoundException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -50,4 +51,8 @@ public class BulkReader {
|
|||||||
return bulkRepository.findDistinctByEntries_Property(property);
|
return bulkRepository.findDistinctByEntries_Property(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<BulkDto> search(final String term) {
|
||||||
|
return RepositorySearchHelper.search(term, bulkRepository, "title", bulkMapper::toDto);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,8 @@ public class KnxGroupChannelOwnerService implements IChannelOwner {
|
|||||||
|
|
||||||
private final KnxGroupReader knxGroupReader;
|
private final KnxGroupReader knxGroupReader;
|
||||||
|
|
||||||
|
private final KnxGroupMapper knxGroupMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestUpdate(final Channel channel) {
|
public void requestUpdate(final Channel channel) {
|
||||||
knxGroupWriter.requestRead((KnxGroup) channel);
|
knxGroupWriter.requestRead((KnxGroup) channel);
|
||||||
@ -36,21 +38,17 @@ public class KnxGroupChannelOwnerService implements IChannelOwner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KnxGroupDto toDto(final long id) {
|
public KnxGroupDto toDto(final long id) {
|
||||||
return toDto(knxGroupReader.getById(id));
|
return knxGroupMapper.toDto(knxGroupReader.getById(id));
|
||||||
}
|
|
||||||
|
|
||||||
public KnxGroupDto toDto(final KnxGroup knxGroup) {
|
|
||||||
return new KnxGroupDto(knxGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<KnxGroupDto> findAllDto() {
|
public List<KnxGroupDto> findAllDto() {
|
||||||
return knxGroupReader.findAll().stream().map(this::toDto).toList();
|
return knxGroupReader.findAll().stream().map(knxGroupMapper::toDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<KnxGroupDto> findAllDtoLikeIgnoreCase(final String like) {
|
public List<KnxGroupDto> findAllDtoLikeIgnoreCase(final String term) {
|
||||||
return knxGroupReader.findAllLike(like).stream().map(this::toDto).toList();
|
return knxGroupReader.search(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.knx.group;
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.RepositorySearchHelper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -17,6 +18,8 @@ public class KnxGroupReader {
|
|||||||
|
|
||||||
private final KnxGroupRepository knxGroupRepository;
|
private final KnxGroupRepository knxGroupRepository;
|
||||||
|
|
||||||
|
private final KnxGroupMapper knxGroupMapper;
|
||||||
|
|
||||||
public Optional<KnxGroup> getByAddress(final int main, final int mid, final int sub) {
|
public Optional<KnxGroup> getByAddress(final int main, final int mid, final int sub) {
|
||||||
return knxGroupRepository.findByAddressRaw(new GroupAddress(main, mid, sub).getRawAddress());
|
return knxGroupRepository.findByAddressRaw(new GroupAddress(main, mid, sub).getRawAddress());
|
||||||
}
|
}
|
||||||
@ -33,4 +36,8 @@ public class KnxGroupReader {
|
|||||||
return knxGroupRepository.findById(id).orElseThrow(RuntimeException::new);
|
return knxGroupRepository.findById(id).orElseThrow(RuntimeException::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<KnxGroupDto> search(final String term) {
|
||||||
|
return RepositorySearchHelper.search(term, knxGroupRepository, "name", knxGroupMapper::toDto);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
package de.ph87.homeautomation.knx.group;
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface KnxGroupRepository extends CrudRepository<KnxGroup, Long> {
|
public interface KnxGroupRepository extends CrudRepository<KnxGroup, Long>, JpaSpecificationExecutor<KnxGroup> {
|
||||||
|
|
||||||
Optional<KnxGroup> findByAddressRaw(int rawAddress);
|
Optional<KnxGroup> findByAddressRaw(int rawAddress);
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,7 @@ public class PropertyController implements ISearchController {
|
|||||||
@Override
|
@Override
|
||||||
@PostMapping("searchLike")
|
@PostMapping("searchLike")
|
||||||
public List<SearchResult> searchLike(@RequestBody final String term) {
|
public List<SearchResult> searchLike(@RequestBody final String term) {
|
||||||
return propertyReader.findAllDtoLike("%" + term + "%").stream().map(this::toSearchResult).toList();
|
return propertyReader.search(term).stream().map(this::toSearchResult).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchResult toSearchResult(final PropertyDto propertyDto) {
|
private SearchResult toSearchResult(final PropertyDto propertyDto) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.property;
|
package de.ph87.homeautomation.property;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.RepositorySearchHelper;
|
||||||
import de.ph87.homeautomation.web.NotFoundException;
|
import de.ph87.homeautomation.web.NotFoundException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -22,8 +23,8 @@ public class PropertyReader {
|
|||||||
return propertyRepository.findAllByReadChannel_Id(readChannelId);
|
return propertyRepository.findAllByReadChannel_Id(readChannelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PropertyDto> findAllDtoLike(final String like) {
|
public List<PropertyDto> search(final String term) {
|
||||||
return propertyRepository.findAllByTitleLikeIgnoreCase(like).stream().map(propertyMapper::toDto).toList();
|
return RepositorySearchHelper.search(term, propertyRepository, "title", propertyMapper::toDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyDto getDtoById(final long id) {
|
public PropertyDto getDtoById(final long id) {
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
package de.ph87.homeautomation.property;
|
package de.ph87.homeautomation.property;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface PropertyRepository extends JpaRepository<Property, Long> {
|
public interface PropertyRepository extends JpaRepository<Property, Long>, JpaSpecificationExecutor<Property> {
|
||||||
|
|
||||||
Optional<Property> findByTitle(String title);
|
Optional<Property> findByTitle(String title);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user