用 $sort + $group($first) + hint 替代 $max,配合复合索引
{mId:1,status:1,reviewAt:-1} 减少 key examined。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
package vidmod
|
||
|
||
import (
|
||
"time"
|
||
|
||
"go.mongodb.org/mongo-driver/bson"
|
||
"go.mongodb.org/mongo-driver/mongo/options"
|
||
)
|
||
|
||
type ModuleLatestAt struct {
|
||
ModuleID string `bson:"_id"`
|
||
LatestAt time.Time `bson:"latestAt"`
|
||
}
|
||
|
||
// LatestReviewAt 返回过滤条件下最近一次审核通过时间。
|
||
func LatestReviewAt(filter bson.M) (*time.Time, error) {
|
||
var list []VideoModel
|
||
opts := options.Find().
|
||
SetSort(bson.D{{Key: "reviewAt", Value: -1}, {Key: "_id", Value: -1}}).
|
||
SetLimit(1).
|
||
SetProjection(bson.M{"reviewAt": 1})
|
||
if err := coll(nil).Find(&list, filter, opts); err != nil {
|
||
return nil, err
|
||
}
|
||
if len(list) == 0 || list[0].ReviewAt.IsZero() {
|
||
return nil, nil
|
||
}
|
||
latest := list[0].ReviewAt
|
||
return &latest, nil
|
||
}
|
||
|
||
// LatestReviewAtByModules 批量返回各亚模块最近一次内容审核通过时间。
|
||
// 用 $sort + $group($first) + hint 替代 $max:
|
||
// 配合 {mId:1,status:1,reviewAt:-1} 索引后,MongoDB 对每个 mId 只扫到首个 key 即可返回,
|
||
// 相较 $max 需要全量扫描所有匹配 key,key examined 可从数万级降到约 len(moduleIDs)。
|
||
func LatestReviewAtByModules(moduleIDs []string) (map[string]time.Time, error) {
|
||
result := make(map[string]time.Time, len(moduleIDs))
|
||
if len(moduleIDs) == 0 {
|
||
return result, nil
|
||
}
|
||
pipeline := []bson.M{
|
||
{"$match": bson.M{
|
||
"status": CheckPass,
|
||
"mId": bson.M{"$in": moduleIDs},
|
||
}},
|
||
{"$sort": bson.D{{Key: "mId", Value: 1}, {Key: "reviewAt", Value: -1}}},
|
||
{"$group": bson.M{
|
||
"_id": "$mId",
|
||
"latestAt": bson.M{"$first": "$reviewAt"},
|
||
}},
|
||
}
|
||
opts := options.Aggregate().SetHint(bson.D{
|
||
{Key: "mId", Value: 1},
|
||
{Key: "status", Value: 1},
|
||
{Key: "reviewAt", Value: -1},
|
||
})
|
||
var rows []ModuleLatestAt
|
||
if err := coll(nil).Aggregate(&rows, pipeline, opts); err != nil {
|
||
return nil, err
|
||
}
|
||
for _, row := range rows {
|
||
if row.ModuleID != "" && !row.LatestAt.IsZero() {
|
||
result[row.ModuleID] = row.LatestAt
|
||
}
|
||
}
|
||
return result, nil
|
||
}
|