Refine event filtering logic to enforce combined match criteria for Authors, Kinds, Tags, and search terms.
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"lol.mleku.dev/chk"
|
"lol.mleku.dev/chk"
|
||||||
"next.orly.dev/pkg/database/indexes/types"
|
"next.orly.dev/pkg/database/indexes/types"
|
||||||
|
"next.orly.dev/pkg/encoders/event"
|
||||||
"next.orly.dev/pkg/encoders/filter"
|
"next.orly.dev/pkg/encoders/filter"
|
||||||
"next.orly.dev/pkg/interfaces/store"
|
"next.orly.dev/pkg/interfaces/store"
|
||||||
)
|
)
|
||||||
@@ -59,7 +60,58 @@ func (d *D) QueryForIds(c context.Context, f *filter.F) (
|
|||||||
idPkTs = append(idPkTs, idpk)
|
idPkTs = append(idPkTs, idpk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If search is combined with Authors/Kinds/Tags, require events to match ALL of those present fields in addition to the word match.
|
||||||
|
if len(f.Search) > 0 && ((f.Authors != nil && f.Authors.Len() > 0) || (f.Kinds != nil && f.Kinds.Len() > 0) || (f.Tags != nil && f.Tags.Len() > 0)) {
|
||||||
|
// Build serial list for fetching full events
|
||||||
|
serials := make([]*types.Uint40, 0, len(idPkTs))
|
||||||
|
for _, v := range idPkTs {
|
||||||
|
s := new(types.Uint40)
|
||||||
|
s.Set(v.Ser)
|
||||||
|
serials = append(serials, s)
|
||||||
|
}
|
||||||
|
var evs map[uint64]*event.E
|
||||||
|
if evs, err = d.FetchEventsBySerials(serials); chk.E(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filtered := make([]*store.IdPkTs, 0, len(idPkTs))
|
||||||
|
for _, v := range idPkTs {
|
||||||
|
ev, ok := evs[v.Ser]
|
||||||
|
if !ok || ev == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matchesAll := true
|
||||||
|
if f.Authors != nil && f.Authors.Len() > 0 && !f.Authors.Contains(ev.Pubkey) {
|
||||||
|
matchesAll = false
|
||||||
|
}
|
||||||
|
if matchesAll && f.Kinds != nil && f.Kinds.Len() > 0 && !f.Kinds.Contains(ev.Kind) {
|
||||||
|
matchesAll = false
|
||||||
|
}
|
||||||
|
if matchesAll && f.Tags != nil && f.Tags.Len() > 0 {
|
||||||
|
// Require the event to satisfy all tag filters as in MatchesIgnoringTimestampConstraints
|
||||||
|
tagOK := true
|
||||||
|
for _, t := range *f.Tags {
|
||||||
|
if t.Len() < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key := t.Key()
|
||||||
|
values := t.T[1:]
|
||||||
|
if !ev.Tags.ContainsAny(key, values) {
|
||||||
|
tagOK = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !tagOK {
|
||||||
|
matchesAll = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if matchesAll {
|
||||||
|
filtered = append(filtered, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idPkTs = filtered
|
||||||
|
}
|
||||||
|
|
||||||
if len(f.Search) == 0 {
|
if len(f.Search) == 0 {
|
||||||
// No search query: sort by timestamp in reverse chronological order
|
// No search query: sort by timestamp in reverse chronological order
|
||||||
sort.Slice(
|
sort.Slice(
|
||||||
|
|||||||
Reference in New Issue
Block a user