Find collections by metadata (exact match)

I am trying to check whether a collection with a specific Dublin Core: Identifier exists. My goal is to create a collection with a particular Identifier if and only if one does not already exist.

If I were looking for items instead of collections, I could perform a search such as

$items = get_records(
    'Item',
    array(
        'advanced' => array(
            array(
                'element_id' => $element_id,
                'type' => 'is exactly',
                'terms' => $identifier,
            )
        )
    )
);

where $element_id is the element ID for Dublin Core: Identifier, and $identifier is the string I want to match. I’ve verified that this search functions properly.

However, if I perform the analogous search for collections, namely

$collections = get_records(
    'Collection',
    array(
        'advanced' => array(
            array(
                'element_id' => $id,
                'type' => 'is exactly',
                'terms' => $identifier,
            )
        )
    )
);

I instead retrieve all collections records up to the limit, even if I search by an Identifier that I know to be unused by any collection.

I would appreciate any suggestions for how I should be trying to determine if a collection with particular metadata fields exists.

Believe it or not, the “advanced” search and the search features in general for Collections just aren’t there.

Some of this has to do with legacy (Collections did not previously support Element metadata), and some of it has to do with usage (Omeka itself doesn’t expose any Collection-specific search page the way it does for items, so we didn’t internally need this). Surprisingly, the change to Collections to make them have Element metadata happened quite some time ago, and you’re one of the very few people (possibly even the first?) who’s specifically noticed or at least mentioned this absence.

As for your current needs: the bottom line is that the built-in filters for Collections just don’t include the filter you need, so get_records with just the core won’t do you much good. All the necessary data is included in the database, so you could either write a plugin to add the “advanced” filter for collections (basically by just copying the code used for the Item advanced filter), or you could execute a custom SQL query to get the result you’re looking for.

The custom query is probably the easier route if you just need to look for one specific value in one element:

$db = get_db();
$table = $db->getTable('Collection');

$sql = <<<SQL
SELECT collections.* FROM `{$db->Collection}` AS collections
INNER JOIN `{$db->ElementText}` AS element_texts ON element_texts.record_id = collections.id
WHERE element_texts.element_id = ? AND element_texts.record_type = 'Collection' AND element_texts.text = ?
GROUP BY collections.id
SQL;

$collections = $table->fetchObjects($sql, array($id, $identifier));

Thank you for this information. I am going to explore adding an advanced filter for collections.