Skip to content

Identifier matching ignores value.uri — URI-typed identifier properties (e.g. owl:sameAs) never match #233

@coret

Description

@coret

Problem

When running an Append/Update/Revise/Replace/Delete CSV import with a resource identifier property whose values are stored as URIs (e.g. owl:sameAs), the importer never finds any existing resource and logs:

The following identifiers are not associated with a resource and were skipped: "...".

for every row, even though the URIs in the CSV exactly match the URIs stored on the items.

Reproducable via

  • Module: CSV Import 2.6.2 on Omeka S 4.2.0.

  • A set of items each has an owl:sameAs value of type URI, e.g. https://n2t.net/ark:/60537/bpMiMT.

  • Description of my TSV (with two columns):

    owl:sameAs<TAB>sdo:description
    https://n2t.net/ark:/60537/bpMiMT<TAB>Some description
    
  • Import via admin GUI:

    • Action: Append
    • Action for unidentified: Skip
    • Resource identifier column: owl:sameAs
    • Resource identifier property: owl:sameAs

Expected: each row is matched to its item and sdo:description is appended.
Actual: every row is skipped; the job log shows "not associated with a resource" for all of them.

Root cause

protected function findResourcesFromPropertyIds($identifiers, $identifierPropertyId, $resourceType)
{
// The api manager doesn't manage this type of search.
$conn = $this->connection;
// Search in multiple resource types in one time.
$quotedIdentifiers = array_map([$conn, 'quote'], $identifiers);
$quotedIdentifiers = implode(',', $quotedIdentifiers);
$qb = $conn->createQueryBuilder()
->select('value.value as identifier', 'value.resource_id as id')
->from('value', 'value')
->leftJoin('value', 'resource', 'resource', 'value.resource_id = resource.id')
->andwhere('value.property_id = :property_id')
->setParameter(':property_id', $identifierPropertyId)
// ->andWhere('value.value in (:values)')
// ->setParameter(':values', $identifiers)
->andWhere("value.value in ($quotedIdentifiers)")
->addOrderBy('resource.id', 'ASC')
->addOrderBy('value.id', 'ASC');

In Omeka S, a property value of type uri is stored with the URI in value.uri and value.value = NULL. The query therefore never matches URI-typed values, regardless of which property is chosen.

Proposed fix

Match against value.uri as well as value.value, and use COALESCE in the projection so cleanResult() can still correlate the row back to the input identifier. Two-line change:

     $qb = $conn->createQueryBuilder()
-        ->select('value.value as identifier', 'value.resource_id as id')
+        ->select('COALESCE(value.value, value.uri) as identifier', 'value.resource_id as id')
         ->from('value', 'value')
         ->leftJoin('value', 'resource', 'resource', 'value.resource_id = resource.id')
         ->andwhere('value.property_id = :property_id')
         ->setParameter(':property_id', $identifierPropertyId)
-        ->andWhere("value.value in ($quotedIdentifiers)")
+        ->andWhere("(value.value in ($quotedIdentifiers) OR value.uri in ($quotedIdentifiers))")
         ->addOrderBy('resource.id', 'ASC')
         ->addOrderBy('value.id', 'ASC');

I've tested this fix: it solved my issue!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions