Skip to content

Commit

Permalink
Merge pull request #165 from LionnoiL/revert-164-213-update-top-adv-a…
Browse files Browse the repository at this point in the history
…lgorithm

Revert "213 update top adv algorithm"
  • Loading branch information
KovalBohdan-0 authored Jul 1, 2024
2 parents fdf1484 + ad394e7 commit 45bf5ef
Show file tree
Hide file tree
Showing 14 changed files with 22 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,4 @@ public List<AdvertisementDetailsResponseDto> setStatusDraft(
.map(adv -> advertisementMapper.mapEntityToDto(adv, defaultSiteLanguage))
.toList();
}

@Operation(summary = "Update Advertisements top rating")
@ApiResponseSuccessful
@ApiResponseUnauthorized
@ApiResponseForbidden
@PutMapping("/top-rating")
public void updateAllTopRatings() {
advertisementService.updateAllTopRatings();
}

@Operation(summary = "Update Advertisements rating")
@ApiResponseSuccessful
@ApiResponseUnauthorized
@ApiResponseForbidden
@PutMapping("/rating")
public void updateAllRatings() {
advertisementService.updateAllRatings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import lombok.*;
import org.hibernate.search.engine.backend.types.Sortable;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.*;
import org.petmarket.advertisements.advertisement.listener.AdvertisementListener;
import org.petmarket.advertisements.attributes.entity.Attribute;
import org.petmarket.advertisements.category.entity.AdvertisementCategory;
import org.petmarket.advertisements.images.entity.AdvertisementImage;
Expand Down Expand Up @@ -33,7 +32,7 @@
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners({AuditingEntityListener.class, AdvertisementListener.class})
@EntityListeners(AuditingEntityListener.class)
@Indexed
public class Advertisement implements TranslateHolder {

Expand Down Expand Up @@ -93,9 +92,6 @@ public class Advertisement implements TranslateHolder {
@GenericField(sortable = Sortable.YES)
private int rating;

@Column(name = "top_rating")
private int topRating;

@ManyToOne
@JoinColumn(name = "breed_id")
@IndexedEmbedded(includeEmbeddedObjectId = true)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public interface AdvertisementRepository extends AdvertisementRepositoryBasic {
WHERE a.category IN :categories
AND a.status = :status
AND a.author.status <> 'DELETED'
ORDER BY a.topRating DESC, a.created DESC
ORDER BY a.created DESC
""")
Page<Advertisement> findAllByCategoryInAndStatusOrderByCreatedDesc(
@Param("categories") List<AdvertisementCategory> categories,
Expand All @@ -85,7 +85,7 @@ Page<Advertisement> findAllByAuthorIdAndStatusAndIdNotOrderByCreatedDesc(Long au
JOIN a.author
WHERE a.status = :status
AND a.author.status <> 'DELETED'
ORDER BY a.topRating DESC, a.created DESC
ORDER BY a.created DESC
""")
Page<Advertisement> findAllByStatusOrderByCreatedDesc(@Param("status") AdvertisementStatus status,
Pageable pageable);
Expand Down Expand Up @@ -166,6 +166,4 @@ void updateStatus(@Param("oldStatus") AdvertisementStatus oldStatus,
List<Advertisement> findAllByOrderId(Long orderId);

List<Advertisement> findAllByAuthorId(Long authorId);

Page<Advertisement> findAllByStatus(AdvertisementStatus status, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.hibernate.search.engine.search.sort.dsl.FieldSortOptionsStep;
import org.hibernate.search.engine.search.sort.dsl.SearchSortFactory;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.massindexing.MassIndexer;
import org.hibernate.search.mapper.orm.scope.SearchScope;
import org.hibernate.search.mapper.orm.session.SearchSession;
import org.petmarket.advertisements.advertisement.dto.AdvertisementDetailsResponseDto;
Expand All @@ -34,6 +33,7 @@
import org.petmarket.errorhandling.ItemNotCreatedException;
import org.petmarket.errorhandling.ItemNotFoundException;
import org.petmarket.language.entity.Language;
import org.petmarket.language.repository.LanguageRepository;
import org.petmarket.location.entity.City;
import org.petmarket.location.entity.Location;
import org.petmarket.location.repository.CityRepository;
Expand Down Expand Up @@ -74,6 +74,7 @@
@Service
public class AdvertisementService {

private final LanguageRepository languageRepository;
private final AdvertisementRepository advertisementRepository;
private final ReviewRepository reviewRepository;
private final UserRepository userRepository;
Expand Down Expand Up @@ -300,13 +301,17 @@ public AdvertisementReviewResponseDto addReview(Long id, AdvertisementReviewRequ
.advertisement(advertisement)
.build();
reviewRepository.save(review);
entityManager.flush();
userCacheService.evictCaches(user);
reviewService.updateAdvertisementIndexes(List.of(advertisement));

return reviewMapper.mapEntityToAdvertisementDto(review);
}

private Language getLanguage(String langCode) {
return languageRepository.findByLangCodeAndEnableIsTrue(langCode)
.orElseThrow(() -> new ItemNotFoundException(LANGUAGE_NOT_FOUND));
}

public Advertisement getAdvertisement(Long id) {
Advertisement advertisement = advertisementRepository.findById(id)
.orElseThrow(() -> new ItemNotFoundException(ADVERTISEMENT_NOT_FOUND));
Expand Down Expand Up @@ -398,113 +403,13 @@ public Page<Advertisement> getSimilarAdvertisements(Long currentAdvertisementId,
return new PageImpl<>(similarAdvertisements, pageable, searchQuery.fetchTotalHitCount());
}

public List<Advertisement> getAdvertisementsByImageIds(List<Long> imageIds) {
return advertisementRepository.findAdvertisementsByImageIds(imageIds);
}

@Transactional
public void updateTopRating(Advertisement advertisement) {
advertisement.setTopRating(calculateRating(advertisement));
entityManager.merge(advertisement);
}

@Transactional
public void updateAllTopRatings() {
int batchSize = 1000;
int page = 0;
Page<Advertisement> advertisements;

do {
advertisements = advertisementRepository
.findAllByStatus(AdvertisementStatus.ACTIVE, PageRequest.of(page, batchSize));

for (Advertisement advertisement : advertisements) {
updateTopRating(advertisement);
}

entityManager.flush();
entityManager.clear();
page++;
} while (advertisements.hasNext());
}

public void updateRating(Review review) {
Advertisement advertisement = review.getAdvertisement();
advertisement.setRating(reviewRepository.findAverageRatingByAdvertisementId(advertisement.getId()));

entityManager.refresh(advertisement);
Search.session(entityManager).indexingPlan().addOrUpdate(advertisement);
}

@Transactional
public void updateAllRatings() {
int batchSize = 1000;
int page = 0;
Page<Advertisement> advertisements;

do {
advertisements = advertisementRepository
.findAllByStatus(AdvertisementStatus.ACTIVE, PageRequest.of(page, batchSize));

for (Advertisement advertisement : advertisements) {
advertisement.setRating(reviewRepository.findAverageRatingByAdvertisementId(advertisement.getId()));
}

entityManager.flush();
entityManager.clear();
page++;
} while (advertisements.hasNext());

page = 0;
Page<User> users;

do {
users = userRepository.findAll(PageRequest.of(page, batchSize));

for (User user : users) {
user.setRating(reviewRepository.findAverageRatingByUserId(user.getId()));
}

entityManager.flush();
entityManager.clear();
page++;
} while (users.hasNext());

SearchSession searchSession = Search.session(entityManager);
MassIndexer indexer = searchSession.massIndexer()
.idFetchSize(150)
.batchSizeToLoadObjects(25)
.threadsToLoadObjects(12);
try {
indexer.startAndWait();
} catch (InterruptedException e) {
log.warn("Failed to load data from database");
Thread.currentThread().interrupt();
}

log.info("All ratings have been updated");
}

public static int calculateRating(Advertisement advertisement) {
return advertisement.getRating() * 10
+ advertisement.getAuthor().getRating() * 10
+ calculateDescriptionLengthBonus(advertisement)
+ calculateImageBonus(advertisement)
+ calculateAttributesBonus(advertisement);
}

private static int calculateDescriptionLengthBonus(Advertisement advertisement) {
return (advertisement.getTranslations() != null && advertisement.getTranslations().stream()
.anyMatch(tr -> tr.getDescription().length() > 20)) ? 30 : 0;
}

private static int calculateImageBonus(Advertisement advertisement) {
return (advertisement.getImages() != null && !advertisement.getImages().isEmpty()) ? 150 : 0;
public Advertisement getAdvertisementByImageId(Long imageId) {
return advertisementRepository.findAdvertisementByImageId(imageId)
.orElseThrow(() -> new ItemNotFoundException(ADVERTISEMENT_NOT_FOUND));
}

private static int calculateAttributesBonus(Advertisement advertisement) {
int bonus = (advertisement.getAttributes() != null ? advertisement.getAttributes().size() : 0) * 30;
return Math.min(bonus, 150);
public List<Advertisement> getAdvertisementsByImageIds(List<Long> imageIds) {
return advertisementRepository.findAdvertisementsByImageIds(imageIds);
}

private Long getCategoryIdFromSearch(String search) {
Expand Down Expand Up @@ -624,6 +529,12 @@ private User getUserByEmail(String email) {
.orElseThrow(() -> new ItemNotFoundException(USER_NOT_FOUND));
}

private AdvertisementTranslate getTranslation(Advertisement advertisement, Language language) {
return advertisement.getTranslations().stream()
.filter(t -> t.getLanguage().equals(language))
.findFirst().orElseThrow(() -> new TranslateException(NO_TRANSLATION));
}

private void addTranslation(Advertisement advertisement, AdvertisementTranslate translation) {
if (checkLanguage(advertisement, translation.getLanguage())) {
throw new TranslateException(LANGUAGE_IS_PRESENT_IN_LIST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.hibernate.search.mapper.orm.massindexing.MassIndexer;
import org.hibernate.search.mapper.orm.session.SearchSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
Expand All @@ -19,16 +18,9 @@ public class HibernateSearchIndexBuild implements ApplicationListener<Applicatio
@Autowired
private EntityManager entityManager;

@Value("${hibernate.search.indexing.startup.enabled}")
private boolean indexOnStartup;

@Override
@Transactional
public void onApplicationEvent(ApplicationReadyEvent event) {
if (!indexOnStartup) {
return;
}

SearchSession searchSession = Search.session(entityManager);
MassIndexer indexer = searchSession.massIndexer()
.idFetchSize(150)
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/org/petmarket/review/dto/AverageReview.java

This file was deleted.

3 changes: 1 addition & 2 deletions src/main/java/org/petmarket/review/entity/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import lombok.*;
import org.petmarket.advertisements.advertisement.entity.Advertisement;
import org.petmarket.order.entity.Order;
import org.petmarket.review.listener.ReviewListener;
import org.petmarket.users.entity.User;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
Expand All @@ -18,7 +17,7 @@
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners({AuditingEntityListener.class, ReviewListener.class})
@EntityListeners(AuditingEntityListener.class)
public class Review {

@Id
Expand Down
63 changes: 0 additions & 63 deletions src/main/java/org/petmarket/review/listener/ReviewListener.java

This file was deleted.

Loading

0 comments on commit 45bf5ef

Please sign in to comment.