API: Apply limit and sort order when searching for IDs #890

This commit is contained in:
Michael Mayer 2021-01-20 12:08:48 +01:00
parent 7631dd7676
commit cb27fc1928
3 changed files with 67 additions and 61 deletions

View file

@ -109,6 +109,7 @@ func AlbumSearch(f form.AlbumSearch) (results AlbumResults, err error) {
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("albums: search %s", form.Serialize(f, true))))
// Base query.
s := UnscopedDb().Table("albums").
Select("albums.*, cp.photo_count, cl.link_count").
Joins("LEFT JOIN (SELECT album_uid, count(photo_uid) AS photo_count FROM photos_albums WHERE hidden = 0 AND missing = 0 GROUP BY album_uid) AS cp ON cp.album_uid = albums.album_uid").
@ -116,6 +117,21 @@ func AlbumSearch(f form.AlbumSearch) (results AlbumResults, err error) {
Where("albums.album_type <> 'folder' OR albums.album_path IN (SELECT photos.photo_path FROM photos WHERE photos.deleted_at IS NULL)").
Where("albums.deleted_at IS NULL")
// Limit result count.
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
// Set sort order.
switch f.Order {
case "slug":
s = s.Order("albums.album_favorite DESC, album_slug ASC")
default:
s = s.Order("albums.album_favorite DESC, albums.album_year DESC, albums.album_month DESC, albums.album_day DESC, albums.album_title, albums.created_at DESC")
}
if f.ID != "" {
s = s.Where("albums.album_uid IN (?)", strings.Split(f.ID, Or))
@ -163,19 +179,6 @@ func AlbumSearch(f form.AlbumSearch) (results AlbumResults, err error) {
s = s.Where("albums.album_day = ?", f.Day)
}
switch f.Order {
case "slug":
s = s.Order("albums.album_favorite DESC, album_slug ASC")
default:
s = s.Order("albums.album_favorite DESC, albums.album_year DESC, albums.album_month DESC, albums.album_day DESC, albums.album_title, albums.created_at DESC")
}
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
if result := s.Scan(&results); result.Error != nil {
return results, result.Error
}

View file

@ -2,6 +2,7 @@ package query
import (
"fmt"
"strings"
"time"
"github.com/gosimple/slug"
@ -20,17 +21,32 @@ func Labels(f form.LabelSearch) (results []LabelResult, err error) {
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("labels: search %s", form.Serialize(f, true))))
s := UnscopedDb()
// s.LogMode(true)
// Base query.
s = s.Table("labels").
Select(`labels.*`).
Where("labels.deleted_at IS NULL").
Where("labels.photo_count > 0").
Group("labels.id")
// Limit result count.
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
// Set sort order.
switch f.Order {
case "slug":
s = s.Order("labels.label_favorite DESC, custom_slug ASC")
default:
s = s.Order("labels.label_favorite DESC, custom_slug ASC")
}
if f.ID != "" {
s = s.Where("labels.label_uid = ?", f.ID)
s = s.Where("labels.label_uid IN (?)", strings.Split(f.ID, Or))
if result := s.Scan(&results); result.Error != nil {
return results, result.Error
@ -74,19 +90,6 @@ func Labels(f form.LabelSearch) (results []LabelResult, err error) {
s = s.Where("labels.label_priority >= 0 OR labels.label_favorite = 1")
}
switch f.Order {
case "slug":
s = s.Order("labels.label_favorite DESC, custom_slug ASC")
default:
s = s.Order("labels.label_favorite DESC, custom_slug ASC")
}
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
if result := s.Scan(&results); result.Error != nil {
return results, result.Error
}

View file

@ -22,10 +22,9 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
}
s := UnscopedDb()
// s.LogMode(true)
// Main search query, avoids (slow) left joins.
// Base query.
s = s.Table("photos").
Select(`photos.*, photos.id AS composite_id,
files.id AS file_id, files.file_uid, files.instance_id, files.file_primary, files.file_missing, files.file_name,
@ -41,6 +40,38 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
Joins("LEFT JOIN lenses ON photos.lens_id = lenses.id").
Joins("LEFT JOIN places ON photos.place_id = places.id")
// Limit result count.
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
// Set sort order.
switch f.Order {
case entity.SortOrderEdited:
s = s.Where("edited_at IS NOT NULL").Order("edited_at DESC, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderRelevance:
if f.Label != "" {
s = s.Order("photo_quality DESC, photos_labels.uncertainty ASC, taken_at DESC, files.file_primary DESC")
} else {
s = s.Order("photo_quality DESC, taken_at DESC, files.file_primary DESC")
}
case entity.SortOrderNewest:
s = s.Order("taken_at DESC, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderOldest:
s = s.Order("taken_at, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderAdded:
s = s.Order("photos.id DESC, files.file_primary DESC")
case entity.SortOrderSimilar:
s = s.Where("files.file_diff > 0")
s = s.Order("photos.photo_color, photos.cell_id, files.file_diff, taken_at DESC, files.file_primary DESC")
case entity.SortOrderName:
s = s.Order("photos.photo_path, photos.photo_name, files.file_primary DESC")
default:
s = s.Order("taken_at DESC, photos.photo_uid, files.file_primary DESC")
}
if !f.Hidden {
s = s.Where("files.file_type = 'jpg' OR files.file_video = 1")
@ -338,37 +369,6 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
s = s.Where("photos.photo_uid NOT IN (SELECT photo_uid FROM photos_albums pa WHERE pa.hidden = 0)")
}
// Set sort order for results.
switch f.Order {
case entity.SortOrderEdited:
s = s.Where("edited_at IS NOT NULL").Order("edited_at DESC, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderRelevance:
if f.Label != "" {
s = s.Order("photo_quality DESC, photos_labels.uncertainty ASC, taken_at DESC, files.file_primary DESC")
} else {
s = s.Order("photo_quality DESC, taken_at DESC, files.file_primary DESC")
}
case entity.SortOrderNewest:
s = s.Order("taken_at DESC, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderOldest:
s = s.Order("taken_at, photos.photo_uid, files.file_primary DESC")
case entity.SortOrderAdded:
s = s.Order("photos.id DESC, files.file_primary DESC")
case entity.SortOrderSimilar:
s = s.Where("files.file_diff > 0")
s = s.Order("photos.photo_color, photos.cell_id, files.file_diff, taken_at DESC, files.file_primary DESC")
case entity.SortOrderName:
s = s.Order("photos.photo_path, photos.photo_name, files.file_primary DESC")
default:
s = s.Order("taken_at DESC, photos.photo_uid, files.file_primary DESC")
}
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
if err := s.Scan(&results).Error; err != nil {
return results, 0, err
}