How do I query for ANY alphanumeric contents in a custom metadata field?

Shamefully, I can’t seem figure out how to run this terribly simple query! :rage:

My goal is to delete some rarely-used custom metadata fields. Some surely have contents, others none at all. I thought an asterisk could pull this off, but that’s a no-go. For instance, if I search the custom metadata field OCLC for [asterisk], I get nothing even though I know I’ve used that field in the past. Anyone know how to do this? Thanks!

Do you only want to delete this meta data in some records or do you want to delete this meta data in all records?

ALL records (I’m deleting the metadata fields themselves). [edit: but obviously not before I first sort out this query issue :slightly_smiling_face:]

I deleted meta data that was no longer necessary some months ago. My goal was to get completely rid of it, as if I never used it. If I recall correctly it wasn’t sufficient to just delete meta data from those records that I assigned meta data to, I had to process all records even those where I was pretty sure they never had this meta data assigned.

To do this you’ll need to

  • install List & Record Tools

  • get the meta data identifiers

    • either via the helper script (which I suggest)
    • or by looking it up in Preferences > Data. There’s no way to copy identifiers from preferences, so make sure you don’t have typos. Also make sure to prefix each meta data identifier with md.
  • set the identifiers in the main script

  • run the main script

  • run the other helper script to check if everything was removed. It creates a text file on your desktop - if everything worked fine the meta data shouldn’t show up there.

Here are the scripts Delete custom metadata fields.

I think I also removed the meta data afterwards from the plist but can’t recall if it was necessary.

Hi Pete. I’m grateful for your detailed response but also a little perplexed.

Is the method you lay out truly necessary to query an existing database’s metadata field for the presence of anything at all? I thought the asterisk (*) could just sort of wildcard search for a purpose such as this, no?

In any case, I’m thankful your method is a reliable one that I can use if I have to.

Over here it wasn’t sufficient to merely set e.g. text type meta data to an empty string. Once the meta data is assigned it will stay assigned, even if it’s empty.

Of course I tried that first and then removed the meta data in Preferences > Data - but it kept coming back. I can’t tell when exactly this happened, however after removing it in preferences it suddenly reappeared in the inspector.

That was by the way the main reason I did all this - I didn’t want to see meta data in the inspector anymore that I no longer wanted to use.

So I’m afraid there’s no other way. If you tell me what type of meta data you want to remove I’ll try how to search for it - given that I already use this type. I won’t create new meta data that I don’t need :sweat_smile:

it kept coming back.

Is this a joke? LOL. I’ll definitely use your method as my goal, as I presume would be anyone’s goal, is not to see this stuff reemerge arbitrarily! [To be clear, this is of course NOT a DEVONthink problem or issue, it’s instead the nature of metadata itself. I’ve run into similar instances like this in the past.]

Unfortunately the List & Record freeware is no longer a downloadable disk image. I’ll search around for an alternate–unless you yourself happen to have the original .dmg for some crazy reason :). I suppose I could also just ask the developer–his page is still up.

My intended little 10-second cleanup is clearly a little more involved than I had thought. Thanks again for the guidance!

Unfortunately no.

Hmm, works over here. (165,9 KB)

You may want to wait some hours to see what others say, however I’m pretty sure there’s no other way.

Hmm, works over here.

Yet another oddity! Thanks so much for the .dmg. Yours downloads just fine. I may as well just do this the right way. Luckily, the total instances of all three metadata fields I intend to inoculate, are extremely few–a couple dozen at most for each one. Thanks again Pete!

[I’m posting here to don’t mix up the threads]

Over here this query


results in all records whose meta data “Bookends” is not empty.

Pete, if you’re swamped, we can kick the can on this. It’s low priority—just an annoyance. I don’t understand what I’m supposed to do with the mdbookends!= operator. I know I’m to swap “bookends” with the actual metadata identifier (from my own metadata). All I need to know, is where that goes. Does this go in one of the scripts you authored and provided in the other thread?

Perhaps a digression, I clicked just now on List & Record Tools.osax in my ScriptingAdditions folder. It launches this, in ScriptEditor:

I’m relieved to understand (through your last comment) that info I wished to acquired, through a query of some sort, can at least be achieved somehow!

1 Like

Sorry @Ryan_N I shouldn’t assume that every user knows DEVONthink’s search syntax.

mdbookends!= is what DEVONthink shows in its search field when you select custom meta data “Bookends” with is not and leave the text field blank.

This results in all records where “Bookends” is not empty

It has nothing to do with the scripts.


Das ist voll fett! @pete31 I’ll come back and edit this after I figure out–with your help hopefully–how to run the “Main” script. (I really do need to learn code!)

I thought that all I had to do, was enter the metadata IDs I wish to permanently delete, but I get an error on the word “permanent.” If you’re willing to edit your script with my IDs, I can simplify the instructions (and this comment) for anyone searching this in the future. In your main script (“Script 2”), my IDs would be: “mdcatalogtitle”, “mdcorr.ocr”, “mddiscoverycredit”, “mdhighinterest?” (In other words, I don’t know how to modify your second (“main”) script to work for me.)

The solution to my OP however, was in your comment just above! :grin:

  1. In the search bar up top, type md[custom metadata ID]!= (excluding brackets, including “!” and “=”) whereas “custom metadata ID” is actually just that, but note: your custom metadata ID might be different than it’s label!
  2. From the list that results, right-click anywhere in the column header labels (i.e. right-click atop the word “Name”). Now click on your custom metadata field from the drop-down list that appears. Next, scroll to the right right (i.e. if you’re on a 13" laptop) and locate the column devoted to the metadata you are examining. Click on that word to sort ascending or descending for ALL instances in your database where that metadata is used.
  • Users who have HAVE NOT deleted custom metadata fields can simply attain the IDs in DT3 in Preferences > Data. They look like this:
  • As the above image demonstrates, a metadata field’s LABEL might be different than its ID. You need the ID.

Pete; a generic question/digression: is there a reason you used the “IS NOT” operator in your query?
For instance, would I get different results using “IS” or “Contains” instead?

  • Users who HAVE already deleted metadata fields, have effectively accomplished the equivalent of squirting a temporary weed killer into the ground; the metadata itself still attached to files, and working from memory is not a reliable way to get rid of it, because the ID for this metadata could differ from its label. The silver bullet solution, therefore, is to run the first of Pete’s three scripts, which furnishes a list of the custom metadata being used by DT according to their respective identifiers. His script produces a list that looks like this:
    scr 2020-12-03 at 11.15.21 AM

So to bring this full circle now, each item on that list should then be queried from within DT3 using the method described in #1 above.

The next step is to run Script 2, the “main” script, to permanently inoculate the unwanted metadata field (but Pete, I’ll need your help first—then will come back here and edit/update this).

Do you mean you ran it but it didn’t remove meta data?


Do you mean meta data is “coming back”? If so: where do you see it coming back? More general: What do you expect as result of running the main script? Did you verify the result with script 3?

Sure, it’s a very nice idea to write proper instructions. That’s often the hardest part when writing and posting scripts, especially as I’m no native speaker (“Das ist voll fett!” :smile:) and it’s often quite hard to anticipate what users need to know.

Click to see the main script with your identifiers
-- Delete Custom Meta Data 

use scripting additions

property deleteMetadataNames : {"mdcatalogtitle", "mdcorr.ocr", "mddiscoverycredit", "mdhighinterest?"} -- set your Meta Data Identifiers here

tell application id "DNtp"
		set theRecords to selection of viewer window 1 as list
		if theRecords = {} then error "Select some records"
		set theButtons to {"Cancel", "Delete"}
		set theButton to button returned of (display alert "Delete this Metadata from selected records?" buttons {item 1, item 2} of theButtons default button 1 message my tid(deleteMetadataNames, linefeed) as critical)
		if theButton = item 1 of theButtons then return
		show progress indicator "Deleting given Metadata... " steps (count theRecords) as string with cancel button
		repeat with thisRecord in theRecords
			step progress indicator (name of thisRecord) as string
			set thisMetadata to custom meta data of thisRecord
				set newMetadata to thisMetadata
				set thePropertyNames to my getPropertyNames(thisMetadata)
				repeat with thisPropertyName in thePropertyNames
					if (thisPropertyName as string) is in deleteMetadataNames then set newMetadata to my deleteUserProperty(thisPropertyName as string, newMetadata)
				end repeat
				if newMetadata ≠ thisMetadata then set custom meta data of thisRecord to newMetadata
			end try
		end repeat
		hide progress indicator
	on error error_message number error_number
		hide progress indicator
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

on tid(theList, theDelimiter)
	set d to AppleScript's text item delimiters
	set AppleScript's text item delimiters to theDelimiter
	set theList to theList as text
	set AppleScript's text item delimiters to d
	return theList
end tid

on getPropertyNames(theMetadata)
	set thePropertyNames to get user property names theMetadata
end getPropertyNames

on deleteUserProperty(thePropertyName, theMetadata)
	set theMetadata_new to delete user property thePropertyName in theMetadata
end deleteUserProperty

If this shouldn’t work as expected please remove identifier mdhighinterest? and try again. Not sure whether the question mark could screw up things.

  • “Is not” with an empty search term gives you all records whose meta data “Bookends” is not empty. That was what you wanted, I think.

  • “Contains” with search term bookends:// would yield the same over here as this meta data holds links, e.g. bookends://

  • “Is” yields in records whose meta data is exactly the search term, e.g. bookends:// finds the record, but if you added a space to the search term you wouldn’t find the record.

That’s all covered in Help > Documentation > Appendix > Search Prefixes.

Curious if it’s working now :slight_smile:

Okay, so I actually entered the syntax properly when I tried this last night. To cover the bases however, I re-ran the script you kindly modified just above (per my request… so huge TY again). I copy all that text, paste it into ScriptEditor (text is purple), then hit the hammer icon. What should happen, is the script converts into lots of black, red and blue, i.e. like above. But what I get instead is "Syntax Error, Expected end of line but found “property.” When it does that, it highlights that literal word, 5th from bottom line of the script. Here are some screenshots–including what I see if I click on the right of the two drop-down menus in ScriptEditor. Note: I’m running DT3.6.1 and Big Sur:

scr 2020-12-03 at 7.25.48 PM
scr 2020-12-03 at 7.25.57 PM

Thank you very much for this explanation. And sorry, I completely forgot to look into what you already mentioned in the other thread

No idea why I didn’t check this, would probably have saved some headache on your side. Sorry!

I just moved List & Record Tools.osax out of /Library/ScriptingAdditions/, and tried to compile again. Same error as yours.

That means List & Record Tools.osax is not installed on your mac.

Please move it to /Library/ScriptingAdditions/, then try to compile again.

Please move it to /Library/ScriptingAdditions/, then try to compile again.

Unfortunately, that’s where I had it. I did a full restart earlier today when I was troubleshooting this. Must be OSX related, but strangely I can double-click the .osax file and see his directory in an AppleScript window. I installed that file per the developer’s instructions by placing it in my user-account ScriptingAdditions folder. But just for kicks, I copied the file and put it in the ScriptingAdditions folder that also exists in the hard drive’s parent “Library” ("Mackintosh HD > “Library” --or in other words; the Library folder that isn’t within my computer’s “user” account–the thing I log-in to when I boot my computer up from a cold start. I initially placed the file under (my username) > Library—i.e. by way of opening the Finder, holding Option and clicking “Go” to access the Library. The file remains there as well.

In my case, it was really only that query you shared that I needed. If the metadata stays, I really don’t care; it won’t be a problem. The only thing that truly suffers is my own mental glory in completing this little task all the way though :crazy_face:. My suspicion is that we’re dealing with an unsolvable conflict with the OS in this case.

Welcome to the troubles of dependencies.

There’s no other way to do it. As far as I know is what “List & Record Tools.osax” does not possible with vanilla AppleScript. Seems its functions could be replicated in AppleScriptObjC, however as long as it works for me I won’t try that. :sweat_smile:

Umm… from the download page of that osaxen:


Change History/Release Notes
1.0.6 June 28, 2010
Support 64-Bit Intel systems.