Search code examples
pythonschemasparqlrdf

SPARQL filter by date for multiple predicates parameters with same subject


I would like to select the car brands (filter contains prefix "dbr:") where schema:Motor and filter schema:dateManufactured > year 2000.

This is the source data (at the bottom you will find my query).

As per RedCrusaderJr answer, we got now the brands but I don't know how to specify the query to filter the date of manufacture and the schema:Motor.

cars = '''@prefix ex: <https://example.org/resource/> .
@prefix schema: <https://schema.org/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dbr: <http://dbpedia.org/resource/> .
@prefix dbo: <http://dbpedia.org/ontology/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

ex:Mustang ex:Deportivo dbr:Ford ;
    schema:Motor ex:Gasolina ;
    ex:potencia "450";
    ex:km "120000";
    schema:dateManufactured "2020-05-29"^^xsd:date ;
    schema:wasInCompetition dbr:LeMans;
    rdfs:label "Ford Mustang GT"@en .

ex:GT ex:Deportivo dbr:Ford ;
    schema:Motor ex:Gasolina ;
    ex:potencia "550";
    ex:km "25000";
    schema:dateManufactured "1968-04-29"^^xsd:date ;
    schema:wasInCompetition dbr:LeMans;
    rdfs:label "Ford GT"@en .

ex:Fiesta ex:Utilitario dbr:Ford ;
    schema:Motor ex:Diesel ;
    ex:potencia "100";
    ex:km "45000";
    schema:dateManufactured "2020-02-10"^^xsd:date ;
    rdfs:label "Ford Fiesta"@en .

ex:206 ex:Utilitario dbr:Peugeot ;
    schema:Motor ex:Diesel ;
    ex:potencia "68";
    ex:km "173100";
    schema:dateManufactured "2004-01-01"^^xsd:date ;
    rdfs:label "Peugeot 206"@en .
   
ex:California ex:Deportivo dbr:Ferrari;
    schema:Motor ex:Gasolina;
    ex:potencia "460";
    ex:km "500000";
    schema:dateManufactured "2010-05-29"^^xsd:date ;
    schema:wasInCompetition dbr:LeMans;
    rdfs:label "Ferrari California"@en .

ex:Enzo ex:Deportivo dbr:Ferrari;
    schema:Motor ex:Gasolina;
    ex:potencia "";
    ex:km "200000";
    schema:dateManufactured "2002-05-29"^^xsd:date ;
    schema:wasInCompetition dbr:LeMans;
    rdfs:label "Ferrari Enzo"@en .

'''


g_q1 = RDFGraph()
g_q1.parse (data=cars, format="turtle")

my initial query ='''
    SELECT ?h 

    {
      ?h schema:Motor ?t;
      :dateManufactured ?date.
      FILTER (?date > "2000-12-31"^^xsd:date)
    }
'''

RedCrusaderJr answer = SELECT * 
{
    {
        SELECT DISTINCT ?o
        { 
            ?s ?p ?o
            FILTER CONTAINS(str(?o), "http://dbpedia.org/resource/")
        }
    }

    #here I understand it would go the schema:motor and date manufactured part.
}

Thanks!


Solution

  • For the follow up on the original question, if I understand you correctly, you want all URIs with a specific prefix, which you'd get with this query:

    SELECT DISTINCT ?o
    {       
       ?s ?p ?o
       FILTER CONTAINS(str(?o), "http://dbpedia.org/resource/")
    }
    

    For your data set you'd get these URIs:

    dbpedia:Ford
    dbpedia:LeMans
    dbpedia:Peugeot
    dbpedia:Delorean_Motor_Company
    dbpedia:Pontiac
    dbpedia:Ferrari
    

    And if you want to use those URIs further on, you can do it like this:

    SELECT * 
    {
        {
            SELECT DISTINCT ?o
            { 
                ?s ?p ?o
                FILTER CONTAINS(str(?o), "http://dbpedia.org/resource/")
            }
        }
    
        #rest of the query where ?o can be used
    }
    

    • EDIT:

    If I run this

    SELECT ?car ?brand ?motor ?dateManufactured
    {
       ?car ex:Deportivo ?brand;
             schema:Motor ?motor;
             schema:dateManufactured ?dateManufactured.
        FILTER (?dateManufactured > "2000-12-31"^^xsd:date)
    }
    

    I get these triples

    car             brand             motor         dateManufactured
    ex:Mustang      dbpedia:Ford      ex:Gasolina   "2020-05-29"
    ex:California   dbpedia:Ferrari   ex:Gasolina   "2010-05-29"
    ex:Enzo         dbpedia:Ferrari   ex:Gasolina   "2002-05-29"
    

    Can you edit your answer again, so I can see exactly what result you want to get? If you want to merge brands with car/motor/dateManufactured, you don't have to get all brands first, but simply use the ex:Deportivo that connect them -> ?car ex:Deportivo ?brand.