How do you sort Tags by number of Items?

I have created a tag called ‘Customer’ with a number of tags for each customer nested within it (e.g. ‘John Doe’). They are all at the same level ‘within’ this customer tag. What I wish to do is sort the tags within this ‘Customer’ tag by the number of items assigned to each one, in descending order. Items are of different file sizes so the ‘by Size’ option, in View > Sort, doesn’t satisfy my requirement.

Is there a straightforward solution to my problem?

1 Like

Welcome @ari
Sorry but this is currently not possible at this time. Perhaps it will be in the future.

Is there a less straightforward solution? A different way I can structure it, so that I may sort by number of items?

At this time, no. The item count isn’t a sortable column, and other attributes, like size or word count, wouldn’t be reliable.

Development would have to assess the potential here.

Alright. I believe it would be a useful feature to add, for my workflow. Evidently, though, it hasn’t been a pressing issue for the community.

Thanks for taking the time to respond.

1 Like

You’re welcome. No promises, but the request has noted. :slight_smile:

1 Like

Hi @ari, if you create a smart group (kind:tag) and attach this triggered script to it (in the info inspector) you can sort your tags with the comment column.

-- Make tags sortable by child count (via finder comment)

-- Assuming you don't use the finder comments of tags (as they will be overwritten) you could attach this triggered script to a smart group that searches for "kind:tag". When you click the smart group it updates the comments.

on triggered(theRecord)
	tell application id "DNtp"
		try
			set theTagGroup to tag group of current database
			
			repeat with thisTag in theTagGroup
				my walkTags(thisTag)
			end repeat
			
		on error error_message number error_number
			if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		end try
	end tell
end triggered

on walkTags(thisTag)
	tell application id "DNtp"
		try
			if type of thisTag = group then
				set theChildCount to (count of (children of thisTag whose type ≠ group)) as string
				set comment of thisTag to theChildCount
			end if
			
			set theChildren to children of thisTag whose type = group as list
			repeat with thisChild in theChildren
				my walkTags(thisChild)
			end repeat
			
		on error error_message number error_number
			if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		end try
	end tell
end walkTags

Hey @pete31, Thanks A lot! I got your solution to work. I only have to adjust my tag hierarchy structure.

How I have it, I include an additional tag on the same level as the items (where the script does its count), with suffixes such as “_paid”. While the items of the “suffixed tags” aren’t included in the child count of the script, Devonthink includes the total count of items, which includes the nested items in those tags. The sort is correct on the first level but Devonthink including the total count of all items nested in that tag, makes it look like it isn’t sorted properly.

This looks strange to anyone who doesn’t understand what is happening in the smart group. But i’m just nitpicking, your solution is functionally sound at the moment, even though Devonthink adds that weird visual quirk. Thanks again.

Try this (I’m quite sure this is not the right way to do it but maybe it’s ok)

-- Sort Tags by child count (via finder comment)

on triggered(theRecord)
	tell application id "DNtp"
		try
			set theTagGroup to tag group of current database
			
			repeat with thisTag in theTagGroup
				my walkTags(thisTag)
				
				set theComments to {}
				
				set theGroups to ((children of thisTag) whose type = group)
				repeat with thisGroup in theGroups
					set end of theComments to comment of thisGroup as string
				end repeat
				
				set addAll to 0
				repeat with thisComment in theComments
					set addAll to addAll + (thisComment as integer)
				end repeat
				set addAll to addAll + (count of (children of thisTag whose type ≠ group))
				
				set comment of thisTag to addAll as string
				
			end repeat
			
		on error error_message number error_number
			if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		end try
	end tell
end triggered

on walkTags(thisTag)
	tell application id "DNtp"
		try
			if type of thisTag = group then
				set theChildCount to (count of (children of thisTag)) as string
				set comment of thisTag to theChildCount
			end if
			
			set theChildren to children of thisTag whose type = group as list
			repeat with thisChild in theChildren
				my walkTags(thisChild)
			end repeat
			
		on error error_message number error_number
			if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		end try
	end tell
end walkTags

I will try it. Thanks again @pete31.

Hey @pete31 is there anyway I can get the script to only include the filtered tags of the smart group I attach it to? Currently it appears to affect all the tags in my database. I want to run the script on the findings of a smart group

You could try to extract the tags from the smart rules search predicates (which is a string), make it a list, and then use this instead of “tag group of current database” in

set theTagGroup to tag group of current database

Hi, I second that request :slight_smile: