[Fix] Return unique search results #1

Merged
bivashy merged 1 commits from fix/prevent-duplicates into main 2025-07-19 18:41:34 +00:00
2 changed files with 43 additions and 3 deletions

View File

@ -13,6 +13,7 @@ import org.springframework.web.server.ResponseStatusException;
import com.backend.search.kodik.service.anyame_backend.api.KodikAPI; import com.backend.search.kodik.service.anyame_backend.api.KodikAPI;
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse; import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse;
import com.backend.search.kodik.service.anyame_backend.component.KodikAPITokenProvider; import com.backend.search.kodik.service.anyame_backend.component.KodikAPITokenProvider;
import com.backend.search.kodik.service.anyame_backend.service.KodikSearchFilterService;
import retrofit2.Response; import retrofit2.Response;
@ -21,10 +22,13 @@ public class SearchController {
Logger log = LoggerFactory.getLogger(SearchController.class); Logger log = LoggerFactory.getLogger(SearchController.class);
private final KodikAPI kodikAPI; private final KodikAPI kodikAPI;
private final KodikAPITokenProvider tokenProvider; private final KodikAPITokenProvider tokenProvider;
private final KodikSearchFilterService searchFilterService;
public SearchController(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider) { public SearchController(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider,
KodikSearchFilterService searchFilterService) {
this.kodikAPI = kodikAPI; this.kodikAPI = kodikAPI;
this.tokenProvider = tokenProvider; this.tokenProvider = tokenProvider;
this.searchFilterService = searchFilterService;
} }
@GetMapping("/search") @GetMapping("/search")
@ -36,8 +40,7 @@ public class SearchController {
response.message()); response.message());
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad response, code: " + response.code()); throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad response, code: " + response.code());
} }
log.info("search result {}", response.body()); return searchFilterService.filter(response.body());
return response.body();
} catch (IOException e) { } catch (IOException e) {
log.warn("i/o error", e); log.warn("i/o error", e);
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "i/o error"); throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "i/o error");

View File

@ -0,0 +1,37 @@
package com.backend.search.kodik.service.anyame_backend.service;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.stereotype.Service;
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse;
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse.Result;
@Service
public class KodikSearchFilterService {
public KodikResponse filter(KodikResponse body) {
Set<String> seenIds = new HashSet<>();
List<Result> filteredResults = body.results.stream().filter(result -> {
String identifier = identifier(result);
boolean updated = seenIds.add(identifier);
return updated;
}).toList();
body.results = filteredResults;
return body;
}
public String identifier(Result result) {
List<String> identifiers = Arrays.asList(result.kinopoiskId,
result.imdbId,
result.shikimoriId,
result.worldartLink);
return identifiers.stream().filter(identifier -> identifier != null && !identifier.isBlank()).findFirst()
.orElse(result.id);
}
}