Skip to content

Commit

Permalink
Merge pull request #94 from nhnacademy-be5-T3Team/feature/elastic
Browse files Browse the repository at this point in the history
Feature/elastic
  • Loading branch information
parkjonggyeong18 authored May 13, 2024
2 parents da3ab35 + b159990 commit 55cf3c6
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.util.List;

@FeignClient(name = "ElasticAdaptor", url = "${t3t.feignClient.url}")
public interface ElasticClient {
Expand Down Expand Up @@ -43,8 +44,19 @@ public interface ElasticClient {
@GetMapping("/t3t/bookstore/category/{categoryId}/search")
ResponseEntity<BaseResponse<PageResponse<ElasticResponse>>>
getCategorySearchPage(@RequestParam String query,
@RequestParam String searchType,
@RequestParam int pageNo,
@PathVariable(value = "categoryId",required = false) BigDecimal categoryId,
@RequestParam(value = "sortBy", defaultValue = "_score", required = false) String sortBy);
@RequestParam String searchType,
@RequestParam int pageNo,
@PathVariable(value = "categoryId",required = false) BigDecimal categoryId,
@RequestParam(value = "sortBy", defaultValue = "_score", required = false) String sortBy);
/**
*
* elasticsearch 기반 실시간 자동완성
*
* @param prefix text 검색어
* @return 서버의 데이터를 가지고 옴
*/
@GetMapping("/t3t/bookstore/autocomplete")
ResponseEntity<BaseResponse<List<String>>> autocomplete(@RequestParam String prefix);
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.t3t.frontserver.elastic.controller;

import com.t3t.frontserver.elastic.client.ElasticClient;
import com.t3t.frontserver.model.response.BaseResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class AutocompleteController {
private final ElasticClient elasticAdaptor;
/**
*
* elasticsearch 기반 실시간 자동완성
*
* @param prefix text 검색어
* @return 페이지로 정보를 가지고 이동
*/

@GetMapping("/autocomplete")
public ResponseEntity<BaseResponse<List<String>>> proxyAutocomplete(@RequestParam String prefix) {
return elasticAdaptor.autocomplete(prefix);
}
}
30 changes: 30 additions & 0 deletions src/main/resources/static/assets/main/css/elastic.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.autocomplete-container {
position: relative;
}

.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
background-color: white;
overflow: hidden;
border-radius: 4px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
font-size: 12px;
}

.autocomplete-items div:hover {
background-color: #e9e9e9;
}
85 changes: 85 additions & 0 deletions src/main/resources/static/assets/main/js/elastic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
document.addEventListener('DOMContentLoaded', function() {
updateSearchTypeDisplay();
updateSearchQueryDisplay();
updateCategoryIdFromURL();

var searchInput = document.getElementById('searchQueryInput');
var resultsContainer = document.getElementById('autocompleteResults');

searchInput.addEventListener('input', function() {
var query = this.value;
if (query.length > 1) {
fetch('/autocomplete?prefix=' + encodeURIComponent(query))
.then(response => response.json())
.then(response => {
if (response.data && response.data.length) {
resultsContainer.innerHTML = '';
response.data.forEach(item => {
var resultItem = document.createElement('div');
resultItem.textContent = item;
resultItem.addEventListener('click', function() {
searchInput.value = this.textContent;
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
});
resultsContainer.appendChild(resultItem);
});
resultsContainer.style.display = 'block';
} else {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
}
})
.catch(error => console.error('Error fetching autocomplete suggestions:', error));
} else {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
}
});

document.addEventListener('click', function(event) {
if (!searchInput.contains(event.target) && !resultsContainer.contains(event.target)) {
resultsContainer.style.display = 'none';
}
});

searchInput.addEventListener('focus', function() {
if (resultsContainer.innerHTML !== '') {
resultsContainer.style.display = 'block';
}
});
});

function updateCategoryIdFromURL() {
const path = window.location.pathname;
const categoryPattern = /\/category\/(\d+)/; // '/category/' 다음에 오는 숫자를 찾는 정규 표현식
const match = path.match(categoryPattern);

if (match && match[1]) {
document.getElementById('categoryIdInput').value = match[1];
} else {
document.getElementById('categoryIdInput').parentNode.removeChild(document.getElementById('categoryIdInput'));
}
}
function setSearchType(type) {
var typeNames = {
'all': '통합검색',
'book_name': '책 이름',
'publisher_name': '출판사',
'participant_name': '참여자'
};
document.getElementById('searchTypeInput').value = type;
document.getElementById('dropdownMenuButton').textContent = typeNames[type];
}
function updateSearchTypeDisplay() {
var searchParams = new URLSearchParams(window.location.search);
var currentType = searchParams.get('searchType') || 'all';
setSearchType(currentType);
}
function updateSearchQueryDisplay() {
var searchParams = new URLSearchParams(window.location.search);
var currentQuery = searchParams.get('query');
if (currentQuery) {
document.getElementById('searchQueryInput').value = currentQuery;
}
}
48 changes: 5 additions & 43 deletions src/main/resources/templates/main/fragment/searchbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ <h5>찾고 싶으신 도서가 있으신가요?</h5>
</div>
</div>
<div class="col-md-6">
<input type="text" class="form-control" placeholder="도서 검색하기" id="searchQueryInput" th:name="query" required>
<input type="text" class="form-control" placeholder="도서 검색하기" id="searchQueryInput" th:name="query" required autocomplete="off">
<div id="autocompleteResults" class="autocomplete-items"></div>
</div>
<div class="col-md-3">
<button class="btn btn-secondary btn-block">검색하기</button>
Expand All @@ -47,46 +48,7 @@ <h5>찾고 싶으신 도서가 있으신가요?</h5>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
updateSearchTypeDisplay();
updateSearchQueryDisplay();
updateCategoryIdFromURL(); // 이 함수를 호출하여 categoryId를 설정
});

function updateCategoryIdFromURL() {
const path = window.location.pathname;
const categoryPattern = /\/category\/(\d+)/; // '/category/' 다음에 오는 숫자를 찾는 정규 표현식
const match = path.match(categoryPattern);

if (match && match[1]) {
document.getElementById('categoryIdInput').value = match[1];
} else {
document.getElementById('categoryIdInput').parentNode.removeChild(document.getElementById('categoryIdInput'));
}
}
function setSearchType(type) {
var typeNames = {
'all': '통합검색',
'book_name': '책 이름',
'publisher_name': '출판사',
'participant_name': '참여자'
};
document.getElementById('searchTypeInput').value = type;
document.getElementById('dropdownMenuButton').textContent = typeNames[type];
}
function updateSearchTypeDisplay() {
var searchParams = new URLSearchParams(window.location.search);
var currentType = searchParams.get('searchType') || 'all';
setSearchType(currentType);
}
function updateSearchQueryDisplay() {
var searchParams = new URLSearchParams(window.location.search);
var currentQuery = searchParams.get('query');
if (currentQuery) {
document.getElementById('searchQueryInput').value = currentQuery;
}
}
</script>
<script th:src="@{/assets/main/js/elastic.js}"></script>
<link th:href="@{/assets/main/css/elastic.css}" rel="stylesheet">
</th:block>
</html>
</html>
2 changes: 1 addition & 1 deletion src/main/resources/templates/main/page/elasticSearch.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ <h2>검색 결과가 없습니다..</h2>
</th:block>
<li class="page-item" th:classappend="${nowPage == endPage} ? 'disabled'">
<a class="page-link"
th:href="@{|/search?query=${query}&searchType=${searchType}&sortBy=${sortBy}&pageNo=${pageNo}${(categoryId != null) ? ('&categoryId=' + categoryId) : ''}|}"
th:href="@{|/search?query=${query}&searchType=${searchType}&sortBy=${sortBy}&pageNo=${nowPage}${(categoryId != null) ? ('&categoryId=' + categoryId) : ''}|}"
aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
Expand Down

0 comments on commit 55cf3c6

Please sign in to comment.