Improve Vertex search result extraction
Some checks are pending
build-push / docker (push) Waiting to run
Some checks are pending
build-push / docker (push) Waiting to run
This commit is contained in:
@@ -263,6 +263,10 @@ func (a *App) searchMedia(c *gin.Context) {
|
|||||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(results) == 0 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"results": []services.AIRecommendation{}, "warning": "Vertex AI Search returned no renderable results. Check your website indexing fields and thumbnails."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
recommended, err := a.GeminiService.Recommend(req.Query, results)
|
recommended, err := a.GeminiService.Recommend(req.Query, results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
neturl "net/url"
|
neturl "net/url"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -121,15 +122,33 @@ func (s *SearchService) searchLite(query string, imageSearch bool) ([]SearchResu
|
|||||||
|
|
||||||
results := make([]SearchResult, 0, len(payload.Results))
|
results := make([]SearchResult, 0, len(payload.Results))
|
||||||
for _, item := range payload.Results {
|
for _, item := range payload.Results {
|
||||||
link := firstString(item.Document.StructData, "link", "url", "uri")
|
link := firstNonEmpty(
|
||||||
title := firstString(item.Document.StructData, "title", "name")
|
firstString(item.Document.DerivedStructData, "link", "url", "uri"),
|
||||||
displayLink := firstString(item.Document.StructData, "site_name", "displayLink")
|
firstString(item.Document.StructData, "link", "url", "uri"),
|
||||||
snippet := firstString(item.Document.DerivedStructData, "snippets", "snippet")
|
)
|
||||||
thumb := firstString(item.Document.DerivedStructData, "link", "thumbnail", "image", "image_url")
|
title := firstNonEmpty(
|
||||||
|
firstString(item.Document.DerivedStructData, "title", "name"),
|
||||||
|
firstString(item.Document.StructData, "title", "name"),
|
||||||
|
)
|
||||||
|
displayLink := firstNonEmpty(
|
||||||
|
firstString(item.Document.DerivedStructData, "displayLink", "site_name"),
|
||||||
|
firstString(item.Document.StructData, "displayLink", "site_name"),
|
||||||
|
)
|
||||||
|
snippet := firstNonEmpty(
|
||||||
|
firstString(item.Document.DerivedStructData, "snippets", "snippet", "extractive_answers"),
|
||||||
|
firstString(item.Document.StructData, "snippets", "snippet", "description"),
|
||||||
|
)
|
||||||
|
thumb := firstNonEmpty(
|
||||||
|
firstString(item.Document.DerivedStructData, "thumbnail", "image", "image_url", "link"),
|
||||||
|
firstString(item.Document.StructData, "thumbnail", "image", "image_url"),
|
||||||
|
)
|
||||||
if thumb == "" {
|
if thumb == "" {
|
||||||
thumb = firstString(item.Document.StructData, "thumbnail", "image", "image_url")
|
thumb = deriveThumbnail(link)
|
||||||
}
|
}
|
||||||
if thumb == "" || link == "" {
|
if title == "" {
|
||||||
|
title = displayLink
|
||||||
|
}
|
||||||
|
if link == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
results = append(results, SearchResult{
|
results = append(results, SearchResult{
|
||||||
@@ -144,6 +163,15 @@ func (s *SearchService) searchLite(query string, imageSearch bool) ([]SearchResu
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func firstNonEmpty(values ...string) string {
|
||||||
|
for _, value := range values {
|
||||||
|
if strings.TrimSpace(value) != "" {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func firstString(values map[string]any, keys ...string) string {
|
func firstString(values map[string]any, keys ...string) string {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
value, ok := values[key]
|
value, ok := values[key]
|
||||||
@@ -161,13 +189,13 @@ func firstString(values map[string]any, keys ...string) string {
|
|||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
if mapped, ok := item.(map[string]any); ok {
|
if mapped, ok := item.(map[string]any); ok {
|
||||||
if text := firstString(mapped, "snippet", "htmlSnippet", "url"); text != "" {
|
if text := firstString(mapped, "snippet", "htmlSnippet", "url", "link", "value", "content"); text != "" {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case map[string]any:
|
case map[string]any:
|
||||||
if text := firstString(typed, "snippet", "htmlSnippet", "url"); text != "" {
|
if text := firstString(typed, "snippet", "htmlSnippet", "url", "link", "value", "content"); text != "" {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,6 +203,30 @@ func firstString(values map[string]any, keys ...string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deriveThumbnail(link string) string {
|
||||||
|
if link == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if videoID := extractYouTubeID(link); videoID != "" {
|
||||||
|
return "https://i.ytimg.com/vi/" + videoID + "/hqdefault.jpg"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractYouTubeID(link string) string {
|
||||||
|
patterns := []*regexp.Regexp{
|
||||||
|
regexp.MustCompile(`(?:v=|\/shorts\/|\/embed\/)([A-Za-z0-9_-]{11})`),
|
||||||
|
regexp.MustCompile(`youtu\.be\/([A-Za-z0-9_-]{11})`),
|
||||||
|
}
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
matches := pattern.FindStringSubmatch(link)
|
||||||
|
if len(matches) == 2 {
|
||||||
|
return matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func inferSource(displayLink string) string {
|
func inferSource(displayLink string) string {
|
||||||
switch {
|
switch {
|
||||||
case strings.Contains(displayLink, "youtube"):
|
case strings.Contains(displayLink, "youtube"):
|
||||||
|
|||||||
Reference in New Issue
Block a user