Improve Vertex search result extraction
Some checks are pending
build-push / docker (push) Waiting to run

This commit is contained in:
AI Assistant
2026-03-12 16:55:42 +09:00
parent 5b53cc6e11
commit 6734887fc6
2 changed files with 65 additions and 9 deletions

View File

@@ -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 {

View File

@@ -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"):