일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Cache
- java
- dbeaver
- java crawler
- Elastic
- request cache
- NORI
- Selenium
- vavr
- API
- 양자컴퓨터
- Aggregation
- redis
- mysql
- Analyzer
- Query
- 테슬라
- KNN
- aqqle
- TSLA
- aggs
- ann
- IONQ
- api cache
- JPA
- Docker
- Elasticsearch
- elasticsearch cache
- file download
- 아이온큐
Archives
- Today
- Total
아빠는 개발자
[Aqqle] API shop service 본문
728x90
반응형
이것도 정리 한번 해보자
개선 포인트
- 가독성 향상:
- fetchSource 설정을 별도 메서드로 추출하여 주석이나 메서드명을 통해 의도를 명확히 표현할 수 있습니다.
- 재사용성 증가:
- 동일한 SearchSourceBuilder 초기화 로직을 여러 곳에서 사용할 수 있습니다.
- 변경 용이성:
- 나중에 포함하거나 제외할 필드를 수정해야 할 경우, 한 곳에서만 변경하면 됩니다.
- 주석 추가:
- includeFields와 excludeFields의 목적을 설명하면, 다른 개발자가 빠르게 코드를 이해할 수 있습니다.
package com.doo.aqqle.service;
import com.doo.aqqle.HostUrl;
import com.doo.aqqle.component.TextEmbedding;
import com.doo.aqqle.component.query.LocationSearchQuery;
import com.doo.aqqle.component.query.ShopSearchQuery;
import com.doo.aqqle.component.response.DataResponse;
import com.doo.aqqle.dto.TextEmbeddingDTO;
import com.doo.aqqle.model.CommonResult;
import com.doo.aqqle.model.request.LocationRequest;
import com.doo.aqqle.model.request.ShopRequest;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
@Service
@RequiredArgsConstructor
public class ShopService {
private final ResponseService responseService;
private final ShopSearchQuery query;
private final LocationSearchQuery locaton;
private final DataResponse response;
public CommonResult getProducts(ShopRequest request) {
try {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String[] includeFields = new String[]{};
String[] excludeFields = new String[]{"feature_vector"};
searchSourceBuilder.fetchSource(includeFields, excludeFields);
FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = null;
Script script = new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1", new HashMap<>());
if ("Y".equals(request.getSimilarity())) {
Vector<Double> vectors = TextEmbedding.getVector(
TextEmbeddingDTO.builder()
.tensorApiUrl(HostUrl.EMBEDDING.getUrl())
.keyword(request.getSearchWord()).build()
);
Map<String, Object> map = new HashMap<>();
map.put("query_vector", vectors);
script = new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "cosineSimilarity(params.query_vector, 'feature_vector') + 1.0", map);
}
filterFunctionBuilders = query.getShopFunctionScoreQueryBuilder(script);
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(
query.getShopQueryBuilder(request.getSearchWord()),
filterFunctionBuilders
);
LocationRequest locationRequest = new LocationRequest();
locationRequest.setDistance("5");
locationRequest.setCountryCode("KR");
locationRequest.setSize(10);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("LOCATION", response.dataResponse(locaton.getDistanceBuilder(locationRequest), locationRequest));
resultMap.put("ITEM", response.shopDataResponse(functionScoreQueryBuilder, request));
return responseService.getSingleResult(resultMap);
} catch (IOException e) {
e.printStackTrace();
}
return responseService.getFailResult();
}
}
변경된 코드
@Service
@RequiredArgsConstructor
public class ShopService {
private final ResponseService responseService;
private final ShopSearchQuery query;
private final LocationSearchQuery locationQuery;
private final DataResponse response;
public CommonResult getProducts(ShopRequest request) {
try {
SearchSourceBuilder searchSourceBuilder = initializeSearchSourceBuilder();
Script script = "Y".equals(request.getSimilarity()) ? createSimilarityScript(request.getSearchWord()) : getDefaultScript();
FunctionScoreQueryBuilder functionScoreQueryBuilder = buildFunctionScoreQuery(script, request);
LocationRequest locationRequest = new LocationRequest("5", "KR", 10);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("LOCATION", response.dataResponse(locationQuery.getDistanceBuilder(locationRequest), locationRequest));
resultMap.put("ITEM", response.shopDataResponse(functionScoreQueryBuilder, request));
return responseService.getSingleResult(resultMap);
} catch (IOException e) {
log.error("Error while fetching products: {}", e.getMessage(), e);
return responseService.getFailResult();
}
}
private SearchSourceBuilder initializeSearchSourceBuilder() {
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.fetchSource(new String[]{}, new String[]{"feature_vector"});
return builder;
}
private Script createSimilarityScript(String searchWord) throws IOException {
Vector<Double> vectors = TextEmbedding.getVector(
TextEmbeddingDTO.builder()
.tensorApiUrl(HostUrl.EMBEDDING.getUrl())
.keyword(searchWord).build()
);
Map<String, Object> params = new HashMap<>();
params.put("query_vector", vectors);
return new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "cosineSimilarity(params.query_vector, 'feature_vector') + 1.0", params);
}
private Script getDefaultScript() {
return new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1", new HashMap<>());
}
private FunctionScoreQueryBuilder buildFunctionScoreQuery(Script script, ShopRequest request) {
FunctionScoreQueryBuilder.FilterFunctionBuilder[] filterFunctionBuilders = query.getShopFunctionScoreQueryBuilder(script);
return new FunctionScoreQueryBuilder(
query.getShopQueryBuilder(request.getSearchWord()),
filterFunctionBuilders
);
}
}
728x90
반응형
'Aqqle > API' 카테고리의 다른 글
[Aqqle] API pakage 구성 (0) | 2025.01.04 |
---|---|
[Aqqle] shop api restcontroller (0) | 2025.01.04 |
[Aqqle] API architecture (1) | 2024.08.31 |