わいえむねっと

Contents
Categories
Calendar
2026/08
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Monthly Archives
~2000/01
Recent Entries
RSS1.0
Templates
Information
Processed: 0.077 sec
Chashed: -
2026/08/16 Sun

TweetVault③

絞り込み機能の拡張

標準だと「テキストボックスに入力した単一ワード」+「一覧から選択した単一タグ」の絞り込みにしか対応していないので、複数条件で絞り込めるようにしたい。

  • 複数ワードの絞り込みに対応
  • テキストボックスに「#xxx」の形式で入力した場合にタグとして絞り込む。複数指定可。一覧で選択したタグとAND。
  • テキストボックスに「-#xxx」の形式で入力した場合にタグを含まないものに絞り込む。複数指定可。

backend/internal/services/bookmark_service.go
@@ -7,2 +7,3 @@
     "strconv"
+    "strings"
 
@@ -196,2 +197,7 @@
 
+    type Tag struct {
+        Name string `json:"name"`
+    }
+    var tags []Tag
+
     query := s.db.Model(&models.BookmarkView{})
@@ -205,3 +211,3 @@
     } else if tag != "" {
-        query = query.Where("tags_json::jsonb @> ?", fmt.Sprintf(`[{"name":"%s"}]`, tag))
+        tags = append(tags, Tag{Name: tag})
     }
@@ -210,4 +216,20 @@
     if search != "" {
-        query = query.Where("full_text ILIKE ? OR name ILIKE ? OR screen_name ILIKE ?",
-            "%"+search+"%", "%"+search+"%", "%"+search+"%")
+        words := strings.Fields(search)
+        for _, word := range words {
+            if strings.HasPrefix(word, "#") {
+                tags = append(tags, Tag{Name: strings.TrimPrefix(word, "#")})
+            } else if strings.HasPrefix(word, "-#") {
+                query = query.Not("tags_json::jsonb @> ?", fmt.Sprintf(`[{"name":"%s"}]`, strings.TrimPrefix(word, "-#")))
+            } else {
+                query = query.Where("full_text ILIKE ? OR name ILIKE ? OR screen_name ILIKE ?",
+                "%"+word+"%", "%"+word+"%", "%"+word+"%")
+            }
+        }
+    }
+    if len(tags) != 0 {
+        jsonData, err := json.Marshal(tags)
+        if err != nil {
+            return nil, 0, err
+        }
+        query = query.Where("tags_json::jsonb @> ?", jsonData)
     }