Problem
When using $not (or other filters) on an @optional property in search criteria, the filter is placed inside an OPTIONAL block in the generated SPARQL. This means it doesn't exclude matching results — it only makes the optional binding unbound.
Example
Schema:
const schema = {
'@type': 'dcat:Dataset',
distribution: {
'@id': 'dcat:distribution',
'@array': true,
'@schema': {
'@type': 'dcat:Distribution',
accessURL: 'dcat:accessURL',
conformsTo: { '@id': 'dcterms:conformsTo', '@optional': true },
},
},
};
Search criteria:
await lens.find({
where: {
distribution: {
conformsTo: { $not: 'https://www.w3.org/TR/rdf-sparql-query/' },
},
},
});
Generated SPARQL (actual)
OPTIONAL {
?iri_1 <dcterms:conformsTo> ?iri_1_1 .
FILTER (?iri_1_1 != "https://www.w3.org/TR/rdf-sparql-query/") .
}
The FILTER is inside the OPTIONAL, so distributions with conformsTo = .../rdf-sparql-query/ still appear — their conformsTo value just becomes unbound.
Expected SPARQL
The filter should be moved outside the OPTIONAL block, using a !BOUND || != pattern:
OPTIONAL {
?iri_1 <dcterms:conformsTo> ?iri_1_1 .
}
FILTER (!BOUND(?iri_1_1) || ?iri_1_1 != "https://www.w3.org/TR/rdf-sparql-query/")
This would correctly exclude distributions whose conformsTo matches, while keeping distributions that have no conformsTo at all.
Version
LDkit 2.6.0
Problem
When using
$not(or other filters) on an@optionalproperty in search criteria, the filter is placed inside anOPTIONALblock in the generated SPARQL. This means it doesn't exclude matching results — it only makes the optional binding unbound.Example
Schema:
Search criteria:
Generated SPARQL (actual)
The
FILTERis inside theOPTIONAL, so distributions withconformsTo = .../rdf-sparql-query/still appear — theirconformsTovalue just becomes unbound.Expected SPARQL
The filter should be moved outside the
OPTIONALblock, using a!BOUND || !=pattern:This would correctly exclude distributions whose
conformsTomatches, while keeping distributions that have noconformsToat all.Version
LDkit 2.6.0