🎨 Improve database rollup field filtering https://github.com/siyuan-note/siyuan/issues/15740

This commit is contained in:
Daniel 2025-09-02 18:37:27 +08:00
parent 7b2e48d54e
commit 04c46b3a56
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
5 changed files with 69 additions and 57 deletions

View file

@ -76,7 +76,7 @@ const (
FilterOperatorIsFalse FilterOperator = "Is false" FilterOperatorIsFalse FilterOperator = "Is false"
) )
func Filter(viewable Viewable, attrView *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()
if 1 > len(filters) { if 1 > len(filters) {
@ -94,8 +94,6 @@ func Filter(viewable Viewable, attrView *AttributeView) {
} }
var items []Item var items []Item
attrViewCache := map[string]*AttributeView{}
attrViewCache[attrView.ID] = attrView
for _, item := range collection.GetItems() { for _, item := range collection.GetItems() {
pass := true pass := true
values := item.GetValues() values := item.GetValues()
@ -116,7 +114,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
break break
} }
if !values[index].Filter(filters[j], attrView, item.GetID(), &attrViewCache) { if !values[index].Filter(filters[j], attrView, item.GetID(), rollupFurtherCollections, cachedAttrViews) {
pass = false pass = false
break break
} }
@ -128,7 +126,7 @@ func Filter(viewable Viewable, attrView *AttributeView) {
collection.SetItems(items) collection.SetItems(items)
} }
func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID string, attrViewCache *map[string]*AttributeView) bool { func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, itemID string, rollupFurtherCollections map[string]Collection, cachedAttrViews map[string]*AttributeView) bool {
if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) { if nil == filter || (nil == filter.Value && nil == filter.RelativeDate) {
return true return true
} }
@ -160,16 +158,16 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false return false
} }
relVal := attrView.GetValue(relKey.ID, rowID) relVal := attrView.GetValue(relKey.ID, itemID)
if nil == relVal || nil == relVal.Relation { if nil == relVal || nil == relVal.Relation {
return false return false
} }
destAv := (*attrViewCache)[relKey.Relation.AvID] destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv { if nil == destAv {
destAv, _ = ParseAttributeView(relKey.Relation.AvID) destAv, _ = ParseAttributeView(relKey.Relation.AvID)
if nil != destAv { if nil != destAv {
(*attrViewCache)[relKey.Relation.AvID] = destAv cachedAttrViews[relKey.Relation.AvID] = destAv
} }
} }
if nil == destAv { if nil == destAv {
@ -181,7 +179,7 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
return false return false
} }
value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, nil) value.Rollup.BuildContents(destAv.KeyValues, destKey, relVal, key.Rollup.Calc, rollupFurtherCollections[key.ID])
for _, content := range value.Rollup.Contents { for _, content := range value.Rollup.Contents {
switch filter.Operator { switch filter.Operator {
case FilterOperatorContains: case FilterOperatorContains:

View file

@ -1465,16 +1465,16 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
return return
} }
attrViewCache := map[string]*av.AttributeView{} cachedAttrViews := map[string]*av.AttributeView{}
avIDs := strings.Split(avs, ",") avIDs := strings.Split(avs, ",")
for _, avID := range avIDs { for _, avID := range avIDs {
attrView := attrViewCache[avID] attrView := cachedAttrViews[avID]
if nil == attrView { if nil == attrView {
attrView, _ = av.ParseAttributeView(avID) attrView, _ = av.ParseAttributeView(avID)
if nil == attrView { if nil == attrView {
return return
} }
attrViewCache[avID] = attrView cachedAttrViews[avID] = attrView
} }
if !attrView.ExistBoundBlock(nodeID) { if !attrView.ExistBoundBlock(nodeID) {
@ -1572,42 +1572,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
// 再渲染关联和汇总 // 再渲染关联和汇总
rollupFurtherCollections := map[string]av.Collection{} rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
for _, kv := range keyValues {
if av.KeyTypeRollup != kv.Key.Type {
continue
}
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
if nil == relKey {
continue
}
destAv := attrViewCache[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv {
continue
}
attrViewCache[relKey.Relation.AvID] = destAv
}
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
if nil == destKey {
continue
}
isSameAv := destAv.ID == attrView.ID
var furtherCollection av.Collection
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
viewable := sql.RenderView(destAv, destAv.Views[0], "")
if nil != viewable {
furtherCollection = viewable.(av.Collection)
}
}
rollupFurtherCollections[kv.Key.ID] = furtherCollection
}
for _, kv := range keyValues { for _, kv := range keyValues {
switch kv.Key.Type { switch kv.Key.Type {
case av.KeyTypeRollup: case av.KeyTypeRollup:
@ -1622,13 +1587,13 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID) relVal := attrView.GetValue(kv.Key.Rollup.RelationKeyID, kv.Values[0].BlockID)
if nil != relVal && nil != relVal.Relation { if nil != relVal && nil != relVal.Relation {
destAv := attrViewCache[relKey.Relation.AvID] destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv { if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID) destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv { if nil == destAv {
break break
} }
attrViewCache[relKey.Relation.AvID] = destAv cachedAttrViews[relKey.Relation.AvID] = destAv
} }
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID) destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
@ -1642,14 +1607,14 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
break break
} }
destAv := attrViewCache[kv.Key.Relation.AvID] destAv := cachedAttrViews[kv.Key.Relation.AvID]
if nil == destAv { if nil == destAv {
destAv, _ = av.ParseAttributeView(kv.Key.Relation.AvID) destAv, _ = av.ParseAttributeView(kv.Key.Relation.AvID)
if nil == destAv { if nil == destAv {
break break
} }
attrViewCache[kv.Key.Relation.AvID] = destAv cachedAttrViews[kv.Key.Relation.AvID] = destAv
} }
blocks := map[string]*av.Value{} blocks := map[string]*av.Value{}
@ -2070,8 +2035,10 @@ func GetCurrentAttributeViewImages(avID, viewID, query string) (ret []string, er
view = attrView.GetView(attrView.ViewID) view = attrView.GetView(attrView.ViewID)
} }
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
table := getAttrViewTable(attrView, view, query) table := getAttrViewTable(attrView, view, query)
av.Filter(table, attrView) av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView) av.Sort(table, attrView)
ids := map[string]bool{} ids := map[string]bool{}
@ -3284,8 +3251,10 @@ func getNewValueByNearItem(nearItem av.Item, key *av.Key, addingBlockID string)
} }
func getNearItem(attrView *av.AttributeView, view, groupView *av.View, previousItemID string) (ret av.Item) { func getNearItem(attrView *av.AttributeView, view, groupView *av.View, previousItemID string) (ret av.Item) {
cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
viewable := sql.RenderGroupView(attrView, view, groupView, "") viewable := sql.RenderGroupView(attrView, view, groupView, "")
av.Filter(viewable, attrView) av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(viewable, attrView) av.Sort(viewable, attrView)
items := viewable.(av.Collection).GetItems() items := viewable.(av.Collection).GetItems()
if 0 < len(items) { if 0 < len(items) {

View file

@ -377,7 +377,9 @@ func renderViewableInstance(viewable av.Viewable, view *av.View, attrView *av.At
return return
} }
av.Filter(viewable, attrView) cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(viewable, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(viewable, attrView) av.Sort(viewable, attrView)
av.Calc(viewable, attrView) av.Calc(viewable, attrView)

View file

@ -83,7 +83,9 @@ func ExportAv2CSV(avID, blockID string) (zipPath string, err error) {
table := getAttrViewTable(attrView, view, "") table := getAttrViewTable(attrView, view, "")
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474 // 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
av.Filter(table, attrView) cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView) av.Sort(table, attrView)
exportFolder := filepath.Join(util.TempDir, "export", "csv", name) exportFolder := filepath.Join(util.TempDir, "export", "csv", name)
@ -2544,7 +2546,9 @@ func exportTree(tree *parse.Tree, wysiwyg, keepFold, avHiddenCol bool,
table := getAttrViewTable(attrView, view, "") table := getAttrViewTable(attrView, view, "")
// 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474 // 遵循视图过滤和排序规则 Use filtering and sorting of current view settings when exporting database blocks https://github.com/siyuan-note/siyuan/issues/10474
av.Filter(table, attrView) cachedAttrViews := map[string]*av.AttributeView{}
rollupFurtherCollections := sql.GetFurtherCollections(attrView, cachedAttrViews)
av.Filter(table, attrView, rollupFurtherCollections, cachedAttrViews)
av.Sort(table, attrView) av.Sort(table, attrView)
var aligns []int var aligns []int

View file

@ -518,6 +518,45 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
} }
} }
func GetFurtherCollections(attrView *av.AttributeView, cachedAttrViews map[string]*av.AttributeView) (ret map[string]av.Collection) {
ret = map[string]av.Collection{}
for _, kv := range attrView.KeyValues {
if av.KeyTypeRollup != kv.Key.Type {
continue
}
relKey, _ := attrView.GetKey(kv.Key.Rollup.RelationKeyID)
if nil == relKey {
continue
}
destAv := cachedAttrViews[relKey.Relation.AvID]
if nil == destAv {
destAv, _ = av.ParseAttributeView(relKey.Relation.AvID)
if nil == destAv {
continue
}
cachedAttrViews[relKey.Relation.AvID] = destAv
}
destKey, _ := destAv.GetKey(kv.Key.Rollup.KeyID)
if nil == destKey {
continue
}
isSameAv := destAv.ID == attrView.ID
var furtherCollection av.Collection
if av.KeyTypeTemplate == destKey.Type || (!isSameAv && (av.KeyTypeUpdated == destKey.Type || av.KeyTypeCreated == destKey.Type)) {
viewable := RenderView(destAv, destAv.Views[0], "")
if nil != viewable {
furtherCollection = viewable.(av.Collection)
}
}
ret[kv.Key.ID] = furtherCollection
}
return
}
func fillAttributeViewTemplateValues(attrView *av.AttributeView, view *av.View, collection av.Collection, ials map[string]map[string]string) (err error) { func fillAttributeViewTemplateValues(attrView *av.AttributeView, view *av.View, collection av.Collection, ials map[string]map[string]string) (err error) {
items := generateAttrViewItems(attrView, view) items := generateAttrViewItems(attrView, view)
existTemplateField := false existTemplateField := false