SPARQL筛选仅含指定类别食材的食谱实例方法
原有查询错误原因
你写的查询有两个问题,导致结果不符合预期:
- 语法错误:
NOT IN操作符后面的取值列表需要用逗号分隔,不能使用&&逻辑运算符,你写的ex:meat && ex:fish本身就是无效的判断条件 - 逻辑错误:当前查询是逐行匹配「食谱-食材-分类」三元组,只要某一个食材不属于肉/鱼分类,对应的食谱就会被纳入结果。这就导致
ex:recipe1虽然有属于肉类的食材,但它同时关联了植物类食材,匹配到植物类食材这一行时就会通过过滤,被错误返回。这种逐行过滤的写法无法实现「只要食谱包含任意禁类食材就整体排除」的整组判断逻辑。
正确SPARQL写法
使用FILTER NOT EXISTS实现整食谱维度的排除判断即可,逻辑是:匹配所有食谱后,只要该食谱下存在任意一个属于ex:meat或ex:fish分类的食材,就直接把这个食谱从结果中剔除。
SELECT ?recipe WHERE { ?recipe a schema:Recipe . # 排除所有包含肉类、鱼类食材的食谱 FILTER NOT EXISTS { ?recipe schema:recipeIngredient ?ingredient . ?ingredient ex:category ?invalidCat . FILTER(?invalidCat IN (ex:meat, ex:fish)) } }
如果你的数据集里可能存在没有挂分类属性的食材,想要更严谨地保证返回食谱的所有食材都必须属于ex:plant或ex:spice,可以再加一层校验:
SELECT ?recipe WHERE { ?recipe a schema:Recipe . # 第一步:排除含禁选分类食材的食谱 FILTER NOT EXISTS { ?recipe schema:recipeIngredient ?ingredient . ?ingredient ex:category ?invalidCat . FILTER(?invalidCat IN (ex:meat, ex:fish)) } # 第二步:排除含非允许分类食材的食谱 FILTER NOT EXISTS { ?recipe schema:recipeIngredient ?ingredient . ?ingredient ex:category ?cat . FILTER(?cat NOT IN (ex:plant, ex:spice)) } }
结果验证
针对你提供的测试RDF数据,上述查询只会返回预期的ex:recipe2:
ex:recipe1关联了属于ex:meat分类的ex:ingredient3,会被排除规则命中,不会出现在结果中ex:recipe2的两个食材分别属于ex:plant和ex:spice,没有命中排除规则,会正常返回
内容的提问来源于stack exchange,提问作者mr. parchman
相关产品推荐
相关产品推荐

