🎨 Database rollup field filtering rules support "Any", "All", and "None" https://github.com/siyuan-note/siyuan/issues/15609

This commit is contained in:
Daniel 2025-09-02 22:04:29 +08:00
parent 8cefe5ce47
commit a26c72d293
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
2 changed files with 46 additions and 28 deletions

View file

@ -26,11 +26,12 @@ import (
// ViewFilter 描述了视图过滤规则的结构。 // ViewFilter 描述了视图过滤规则的结构。
type ViewFilter struct { type ViewFilter struct {
Column string `json:"column"` // 列字段ID Column string `json:"column"` // 列字段ID
Operator FilterOperator `json:"operator"` // 过滤操作符 Qualifier FilterQuantifier `json:"quantifier,omitempty"` // 量词
Value *Value `json:"value"` // 过滤值 Operator FilterOperator `json:"operator"` // 操作符
RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间 Value *Value `json:"value"` // 过滤值
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间
RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween
} }
type RelativeDateUnit int type RelativeDateUnit int
@ -76,6 +77,15 @@ const (
FilterOperatorIsFalse FilterOperator = "Is false" FilterOperatorIsFalse FilterOperator = "Is false"
) )
type FilterQuantifier string
const (
FilterQuantifierUndefined FilterQuantifier = ""
FilterQuantifierAny FilterQuantifier = "Any"
FilterQuantifierAll FilterQuantifier = "All"
FilterQuantifierNone FilterQuantifier = "None"
)
func Filter(viewable Viewable, attrView *AttributeView, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) { func Filter(viewable Viewable, attrView *AttributeView, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) {
collection := viewable.(Collection) collection := viewable.(Collection)
filters := collection.GetFilters() filters := collection.GetFilters()
@ -147,7 +157,6 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID s
nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) { nil != filter.Value.Rollup && 0 < len(filter.Value.Rollup.Contents) {
// 单独处理汇总类型的比较 // 单独处理汇总类型的比较
// 处理值比较
key, _ := attrView.GetKey(value.KeyID) key, _ := attrView.GetKey(value.KeyID)
if nil == key { if nil == key {
return false return false
@ -180,31 +189,39 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID s
} }
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID]) value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID])
for _, content := range value.Rollup.Contents {
switch filter.Operator { switch filter.Qualifier {
case FilterOperatorContains: case FilterQuantifierUndefined, FilterQuantifierAny:
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) { for _, content := range value.Rollup.Contents {
return true switch filter.Operator {
} case FilterOperatorContains:
case FilterOperatorDoesNotContain: if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
ret := content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) return true
if !ret { }
return false case FilterOperatorDoesNotContain:
} if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
default: return false
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) { }
return true default:
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return true
}
}
}
case FilterQuantifierAll:
for _, content := range value.Rollup.Contents {
if !content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
}
}
return true
case FilterQuantifierNone:
for _, content := range value.Rollup.Contents {
if content.filter(filter.Value.Rollup.Contents[0], filter.RelativeDate, filter.RelativeDate2, filter.Operator) {
return false
} }
} }
}
switch filter.Operator {
case FilterOperatorContains:
return false
case FilterOperatorDoesNotContain:
return true return true
default:
return false
} }
} }

View file

@ -2533,6 +2533,7 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr
for _, filter := range masterView.Filters { for _, filter := range masterView.Filters {
view.Filters = append(view.Filters, &av.ViewFilter{ view.Filters = append(view.Filters, &av.ViewFilter{
Column: filter.Column, Column: filter.Column,
Qualifier: filter.Qualifier,
Operator: filter.Operator, Operator: filter.Operator,
Value: filter.Value, Value: filter.Value,
RelativeDate: filter.RelativeDate, RelativeDate: filter.RelativeDate,