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

View file

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

View file

@ -377,7 +377,9 @@ func renderViewableInstance(viewable av.Viewable, view *av.View, attrView *av.At
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.Calc(viewable, attrView)

View file

@ -83,7 +83,9 @@ func ExportAv2CSV(avID, blockID string) (zipPath string, err error) {
table := getAttrViewTable(attrView, view, "")
// 遵循视图过滤和排序规则 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)
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, "")
// 遵循视图过滤和排序规则 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)
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) {
items := generateAttrViewItems(attrView, view)
existTemplateField := false