Apache Solr – wyszukiwanie pełnotekstowe – inteligentna wyszukiwarka
Apache Solr – wyszukiwanie pełnotekstowe – inteligentna wyszukiwarka
Inteligentna wyszukiwarka to mechanizm który pozwala na podpowiadanie wyszukiwanych przez użytkownika słów. Wpis ten bazuje na danych które zostały zaimportowane z bazy MySQL w poprzednim wpisie dotyczącym Apache Solr – zachęcam do zapoznania się z nim:
https://javaleader.pl/2019/09/24/apache-solr-import-danych-z-uzyciem-bazy-mysql/
Tworzymy nowy projekt Spring Boota – niezbędne zależności – plik pom.xml:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-solr</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
Plik application.properties – konfigurujemy port oraz adres pod którym dostępne jest oprogramowanie Apache Solr:
server.port = 8089 spring.data.solr.host = http://localhost:8983/solr/
Tworzymy model – (solCoreName to nazwa core która skonfigurowana jest w Apache Solr):
@Data @NoArgsConstructor @AllArgsConstructor @SolrDocument(solrCoreName = "comments") public class Comment { @Id @Field private String id; @Field(value = "comment_content") private String commentContent; public Comment(String commentContent) { this.commentContent = commentContent; } }
Serwis:
public interface CommentService { FacetPage<Comment> autocomplete(String query, Pageable pageable); }
Implementacja serwisu:
@Service public class CommentServiceImpl implements CommentService { private final CommentRepository commentRepository; @Autowired public CommentServiceImpl(CommentRepository productRepository) { this.commentRepository = productRepository; } @Override public FacetPage<Comment> autocomplete(String query, Pageable pageable) { if(StringUtils.isBlank(query)) { return new SolrResultPage<>(Collections.emptyList()); } return commentRepository.findByCommentContentIgnoreCaseStartingWith(query, pageable); } }
Repozytorium danych:
Faceting to metoda kategoryzacji treści w oparciu o wskazane kryterium wyszukiwania, repozytorium korzysta z adnotacji @Facet aby prawidłowo mapować zapytania do Apache Solr:
public interface CommentRepository extends SolrCrudRepository<Comment, String> { @Facet(fields = { "comment_content" }) FacetPage<Comment> findByCommentContentIgnoreCaseStartingWith(String commentContent, Pageable pageable); }
oraz kontroler:
@Slf4j @Controller public class CommentController { private final CommentService commentService; @Autowired public CommentController(CommentService commentService) { this.commentService = commentService; } @RequestMapping(value = "/autocomplete", produces = "application/json") public @ResponseBody Set<String> autoComplete(@RequestParam("term") String query, @PageableDefault(page = 0, size = 1) Pageable pageable) { if (!StringUtils.hasText(query)) { return Collections.emptySet(); } FacetPage<Comment> result = commentService.autocomplete(query, pageable); Set<String> titles = new LinkedHashSet<>(); for (Page<FacetFieldEntry> page : result.getFacetResultPages()) { for (FacetFieldEntry entry : page) { Optional<String> entryValue = Optional.ofNullable(entry.getValue()); if(entryValue.isPresent() && entryValue.get().contains(query.toLowerCase())){ titles.add(StringUtils.capitalize(entryValue.get())); } } } return titles; } @GetMapping("/") public String homeSearchPage(){ return "index"; } }
Teraz czas na wyszukiwarkę – plik ./resources/templates/index.html:
<body> <input type="text" id="comment_content" class="form-control" placeholder="Comment content here..."/> </body>
W pliku ./resources/static/js/script.js zamieszczamy kod java script który odpowiedzialny będzie za autouzupełnianie formularza wyszukiwarki w oparciu o dane pobierane z Apache Solr:
$(function() { $("#comment_content") .autocomplete( { source : 'http://localhost:8089/autocomplete', minLength : 1, }); });
Po wejściu na główną stronę aplikacji i wpisaniu w formularzu dwóch pierwszych liter automatycznie pojawią się podpowiedzi zaczerpnięte z użyciem Apache Solr:
Warto dodać wpis css:
<style> .ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } </style>
aby uniknąć zbędnych komunikatów:
Leave a comment