fix(search): fan out only over values the leaf can read - #828
Conversation
Found adapting a downstream schema to ADR 26, against its real data. A role is sometimes stated twice on one node – as a string and as a Wikidata entity – and a keyword leaf reads the literal and passes over the IRI. Fan-out split on both, so the IRI minted a second entry the role was absent from: the same endpoint, apparently in no role at all, shown to a reader and matched by a filter. The split now follows the reader. Only `keyword` needs narrowing: a `text` field has no filter operator, so nothing welds it and it is never a tuple position, and a `reference` is one whose two shapes are both meaningful – an IRI, and a node the graph named inline, which has no IRI and is a referent all the same.
|
Closing: this guards a shape the data does not have. The phantom entry needs two or more values on one weldable leaf, at least one of which the leaf cannot read – a role stated as a literal and as an IRI on the same node. I took that case from a comment in Linked Open Limburg's schema, which says Beeld & Geluid "sometimes states a Wikidata IRI beside the string". Its own documentation says the opposite – "sometimes a Wikidata IRI rather than a string" – so I queried the source rather than pick one. Against SELECT ?r ?lit ?iri WHERE {
?r schema:roleName ?lit , ?iri .
FILTER(isLiteral(?lit) && isIRI(?iri))
} LIMIT 3returns nothing, and a sample of One value per node means no split, so no entry is minted that the leaf is absent from. The fix would change no document in the register. It remains true that schema.org gives The measurement did turn up something worth acting on, in the other direction. B&G's roles being IRIs only means a |
Follow-up to #801, found while adapting Linked Open Limburg’s schema to ADR 26 against its real data.
The defect
A role is sometimes stated twice on one node – once as a string, once as a Wikidata entity. Beeld & Geluid does this, and LOL’s own schema comment noted the IRI “costs nothing and takes nothing away”, which was true while the entry held a list.
Under fan-out it stopped being true.
tuplesOfsplit on every framed value, but akeywordleaf reads literals and passes over an IRI – so the IRI minted a second entry the role was absent from:The same endpoint, apparently in no role at all – shown to a reader, and matched by a filter for that agent. Not a crash and not a hang: a phantom entry that reads as data.
Two things the shape happens to get right, worth stating so the fix is not over-drawn:
keyworddoes drop the IRI, so no rawhttp://…is rendered as a role label, andapplyIdentityCompaniondedupes, so the agent’s id appears once rather than twice.The fix
The split follows the reader.
splittable()narrows a leaf’s framed values to those its kind can read before the product is taken.Only
keywordneeds it:texthas no filter operator (filterOperatorFormaps it toundefined), so nothing welds it and it is never a tuple position;referenceis one, and both of its shapes are meaningful – an IRI, and, for alocallookup, a node the graph named inline, which has no IRI and is a referent all the same.Notes
limburg/lol, its issue 162) is what surfaced this. It needs@lde/search@0.25.0plus this fix.