meals-made-easy-api/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java

75 lines
2.8 KiB
Java

package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.user.User;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Optional;
public interface RecipeRepository extends JpaRepository<Recipe, Integer> {
Slice<Recipe> findAllByIsPublicIsTrue(Pageable pageable);
List<Recipe> findAllByViewersContaining(User viewer);
List<Recipe> findAllByOwner(User owner);
@Query("SELECT r from Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2")
Optional<Recipe> findByOwnerUsernameAndSlug(String ownerUsername, String slug);
@Query("SELECT r FROM Recipe r WHERE size(r.stars) >= ?1 AND (r.isPublic OR ?2 MEMBER OF r.viewers)")
List<Recipe> findAllViewableByStarsGreaterThanEqual(long stars, User viewer);
@Query("SELECT r FROM Recipe r WHERE r.id = ?1")
@EntityGraph(attributePaths = { "viewers" })
Optional<Recipe> findByIdWithViewers(long id);
@Query("SELECT r FROM Recipe r WHERE r.id = ?1")
@EntityGraph(attributePaths = { "stars" })
Optional<Recipe> findByIdWithStars(long id);
@Query("SELECT size(r.stars) FROM Recipe r WHERE r.id = ?1")
int getStarCount(long recipeId);
@Query("SELECT size(r.viewers) FROM Recipe r WHERE r.id = ?1")
int getViewerCount(long recipeId);
@Query("SELECT r FROM Recipe r WHERE r.isPublic OR r.owner = ?1 OR ?1 MEMBER OF r.viewers")
Slice<Recipe> findAllViewableBy(User viewer, Pageable pageable);
List<Recipe> findAllByEmbeddingIsNull();
@Query(
nativeQuery = true,
value = """
WITH distances AS (SELECT recipe_id, embedding <=> cast(?1 AS vector) AS distance FROM recipe_embedding)
SELECT r.* FROM distances d
INNER JOIN recipe r ON r.id = d.recipe_id
WHERE d.distance < ?2 AND (
r.is_public = TRUE
OR r.owner_id = ?3
OR exists(SELECT 1 FROM recipe_viewer v WHERE v.recipe_id = r.id AND v.viewer_id = ?3)
)
ORDER BY d.distance;
"""
)
List<Recipe> searchByEmbeddingAndViewableBy(float[] queryEmbedding, float similarity, Integer viewerId);
@Query(
nativeQuery = true,
value = """
WITH distances AS (SELECT recipe_id, embedding <=> cast(?1 AS vector) AS distance FROM recipe_embedding)
SELECT r.* FROM distances d
INNER JOIN recipe r ON r.id = d.recipe_id
WHERE d.distance < ?2 AND r.is_public = TRUE
ORDER BY d.distance;
"""
)
List<Recipe> searchByEmbeddingAndIsPublic(float[] queryEmbedding, float similarity);
}