Skip to content

Commit

Permalink
added search capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
yu-melody committed Feb 25, 2024
1 parent 57c884f commit 6a854fb
Show file tree
Hide file tree
Showing 8 changed files with 1,737 additions and 17 deletions.
6 changes: 5 additions & 1 deletion backend/src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/GenerateNU/sac/backend/src/config"
"github.com/GenerateNU/sac/backend/src/database"
_ "github.com/GenerateNU/sac/backend/src/docs"
"github.com/GenerateNU/sac/backend/src/search"
"github.com/GenerateNU/sac/backend/src/server"
)

Expand All @@ -29,6 +30,9 @@ func main() {
panic(fmt.Sprintf("Error getting configuration: %s", err.Error()))
}

openAIClient := search.NewOpenAIClient(config.OpenAISettings)
pineconeClient := search.NewPineconeClient(openAIClient, config.PineconeSettings)

db, err := database.ConfigureDB(*config)
if err != nil {
panic(fmt.Sprintf("Error configuring database: %s", err.Error()))
Expand All @@ -43,7 +47,7 @@ func main() {
panic(fmt.Sprintf("Error connecting to database: %s", err.Error()))
}

app := server.Init(db, *config)
app := server.Init(db, *config, *pineconeClient)

err = app.Listen(fmt.Sprintf("%s:%d", config.Application.Host, config.Application.Port))
if err != nil {
Expand Down
1,664 changes: 1,664 additions & 0 deletions backend/src/migrations/data.sql

Large diffs are not rendered by default.

27 changes: 26 additions & 1 deletion backend/src/models/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Club struct {

Name string `gorm:"type:varchar(255)" json:"name" validate:"required,max=255"`
Preview string `gorm:"type:varchar(255)" json:"preview" validate:"required,max=255"`
Description string `gorm:"type:varchar(255)" json:"description" validate:"required,http_url,mongo_url,max=255"` // MongoDB URL
Description string `gorm:"type:varchar(10000)" json:"description" validate:"required,http_url,mongo_url,max=255"` // MongoDB URL
NumMembers int `gorm:"type:int" json:"num_members" validate:"required,min=1"`
IsRecruiting bool `gorm:"type:bool;default:false" json:"is_recruiting" validate:"required"`
RecruitmentCycle RecruitmentCycle `gorm:"type:varchar(255);default:always" json:"recruitment_cycle" validate:"required,max=255,oneof=fall spring fallSpring always"`
Expand Down Expand Up @@ -90,8 +90,33 @@ type ClubQueryParams struct {
IsRecruiting *bool `query:"is_recruiting"`
Limit int `query:"limit"`
Page int `query:"page"`
Search string `query:"search"`
}

type ClubSearch struct {
SearchString string `query:"search"`

Check failure on line 97 in backend/src/models/club.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `goimports`-ed (goimports)
}

func NewClubSearch(searchQuery string) *ClubSearch {
return &ClubSearch{
SearchString: searchQuery,
}
}

// dummy searchID
func (cs *ClubSearch) SearchId() string {
return ""
}

func (cs * ClubSearch) Namespace() string {
return "clubs"
}

func (cs *ClubSearch) EmbeddingString() string {
return cs.SearchString
}


func (cqp *ClubQueryParams) IntoWhere() string {
conditions := make([]string, 0)

Expand Down
5 changes: 3 additions & 2 deletions backend/src/server/routes/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
p "github.com/GenerateNU/sac/backend/src/auth"
"github.com/GenerateNU/sac/backend/src/controllers"
"github.com/GenerateNU/sac/backend/src/middleware"
"github.com/GenerateNU/sac/backend/src/search"
"github.com/GenerateNU/sac/backend/src/services"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)

func ClubRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate, authMiddleware *middleware.AuthMiddlewareService) {
clubIDRouter := Club(router, services.NewClubService(db, validate), authMiddleware)
func ClubRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate, authMiddleware *middleware.AuthMiddlewareService, pineconeClient search.PineconeClient) {
clubIDRouter := Club(router, services.NewClubService(db, validate, pineconeClient), authMiddleware)

ClubTag(clubIDRouter, services.NewClubTagService(db, validate), authMiddleware)
ClubFollower(clubIDRouter, services.NewClubFollowerService(db), authMiddleware)
Expand Down
5 changes: 3 additions & 2 deletions backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/GenerateNU/sac/backend/src/config"
"github.com/GenerateNU/sac/backend/src/middleware"
"github.com/GenerateNU/sac/backend/src/search"
"github.com/GenerateNU/sac/backend/src/server/routes"
"github.com/GenerateNU/sac/backend/src/services"
"github.com/GenerateNU/sac/backend/src/utilities"
Expand All @@ -25,7 +26,7 @@ import (
// @contact.email [email protected] and [email protected]
// @host 127.0.0.1:8080
// @BasePath /
func Init(db *gorm.DB, settings config.Settings) *fiber.App {
func Init(db *gorm.DB, settings config.Settings, pineconeClient search.PineconeClient) *fiber.App {
app := newFiberApp()

validate, err := utilities.RegisterCustomValidators()
Expand All @@ -42,7 +43,7 @@ func Init(db *gorm.DB, settings config.Settings) *fiber.App {
routes.Auth(apiv1, services.NewAuthService(db, validate), settings.Auth, authMiddleware)
routes.UserRoutes(apiv1, db, validate, authMiddleware)
routes.Contact(apiv1, services.NewContactService(db, validate), authMiddleware)
routes.ClubRoutes(apiv1, db, validate, authMiddleware)
routes.ClubRoutes(apiv1, db, validate, authMiddleware, pineconeClient)
routes.Tag(apiv1, services.NewTagService(db, validate), authMiddleware)
routes.CategoryRoutes(apiv1, db, validate, authMiddleware)
routes.Event(apiv1, services.NewEventService(db, validate), authMiddleware)
Expand Down
11 changes: 6 additions & 5 deletions backend/src/services/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ func (a *AuthService) Login(userBody models.LoginUserResponseBody) (*models.User
return nil, &errors.FailedToValidateUser
}

user, err := transactions.GetUserByEmail(a.DB, userBody.Email)
if err != nil {
return nil, err
user, getUserByEmailErr := transactions.GetUserByEmail(a.DB, userBody.Email)
if getUserByEmailErr != nil {
return nil, getUserByEmailErr
}

correct, passwordErr := auth.ComparePasswordAndHash(userBody.Password, user.PasswordHash)
if passwordErr != nil || !correct {

Check failure on line 56 in backend/src/services/auth.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `goimports`-ed (goimports)
correct, err := auth.ComparePasswordAndHash(userBody.Password, user.PasswordHash)
if err != nil || !correct {
return nil, &errors.FailedToValidateUser
}

Expand Down
8 changes: 5 additions & 3 deletions backend/src/services/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package services
import (
"github.com/GenerateNU/sac/backend/src/errors"
"github.com/GenerateNU/sac/backend/src/models"
"github.com/GenerateNU/sac/backend/src/search"
"github.com/GenerateNU/sac/backend/src/transactions"
"github.com/GenerateNU/sac/backend/src/utilities"
"github.com/go-playground/validator/v10"
Expand All @@ -19,12 +20,13 @@ type ClubServiceInterface interface {
}

type ClubService struct {
pineconeClient *search.PineconeClient
DB *gorm.DB
Validate *validator.Validate
}

func NewClubService(db *gorm.DB, validate *validator.Validate) *ClubService {
return &ClubService{DB: db, Validate: validate}
func NewClubService(db *gorm.DB, validate *validator.Validate, pineconeClient search.PineconeClient) *ClubService {
return &ClubService{DB: db, Validate: validate, pineconeClient : &pineconeClient}
}

func (c *ClubService) GetClubs(queryParams *models.ClubQueryParams) ([]models.Club, *errors.Error) {
Expand All @@ -36,7 +38,7 @@ func (c *ClubService) GetClubs(queryParams *models.ClubQueryParams) ([]models.Cl
return nil, &errors.FailedToValidatePage
}

return transactions.GetClubs(c.DB, queryParams)
return transactions.GetClubs(c.DB, queryParams, *c.pineconeClient)
}

func (c *ClubService) CreateClub(clubBody models.CreateClubRequestBody) (*models.Club, *errors.Error) {
Expand Down
28 changes: 25 additions & 3 deletions backend/src/transactions/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package transactions
import (
stdliberrors "errors"

"github.com/GenerateNU/sac/backend/src/search"

"github.com/GenerateNU/sac/backend/src/errors"
"github.com/GenerateNU/sac/backend/src/models"

Expand All @@ -25,7 +27,7 @@ func GetAdminIDs(db *gorm.DB, clubID uuid.UUID) ([]uuid.UUID, *errors.Error) {
return adminUUIDs, nil
}

func GetClubs(db *gorm.DB, queryParams *models.ClubQueryParams) ([]models.Club, *errors.Error) {
func GetClubs(db *gorm.DB, queryParams *models.ClubQueryParams, pineconeClient search.PineconeClient) ([]models.Club, *errors.Error) {
query := db.Model(&models.Club{})

if queryParams.Tags != nil && len(queryParams.Tags) > 0 {
Expand All @@ -38,8 +40,28 @@ func GetClubs(db *gorm.DB, queryParams *models.ClubQueryParams) ([]models.Club,

if queryParams.Tags != nil && len(queryParams.Tags) > 0 {
query = query.Joins("JOIN club_tags ON club_tags.club_id = clubs.id").
Where("club_tags.tag_id IN ?", queryParams.Tags).
Group("clubs.id") // ensure unique club records
Where("club_tags.tag_id IN ?", queryParams.Tags). // add search function here
Group("clubs.id") // ensure unique club records
}


Check failure on line 47 in backend/src/transactions/club.go

View workflow job for this annotation

GitHub Actions / Lint

File is not `goimports`-ed (goimports)
if queryParams.Search != "" {
clubSearch := models.NewClubSearch(queryParams.Search)


resultIDs, err := pineconeClient.Search(clubSearch, 10);
if err != nil {
return nil, &errors.FailedToSearchToPinecone
}

query = query.Where("id IN ?", resultIDs)

// =====================================
// some kind of call to 'CreateEmbedding'
// Use 'search' to search for similar vectors in the pinecone database
// calculate cosine similarity for all vectors returned by pinecone
// return results > a certain score (add it to the query)
// ====================================
}

var clubs []models.Club
Expand Down

0 comments on commit 6a854fb

Please sign in to comment.