5 Replies Latest reply on Apr 11, 2008 5:44 PM by alwu-Oracle

    Another query question

    user625573
      Is there a way to execute a SEM_MATCH-like query, but in a way that returns the set of triples in the subgraph that match the query pattern, instead of the table of named variables? This would achieve the same as SPARQL DESCRIBE queries, and is a very useful way to extract subgraphs from models.

      Regards,
      Jan
        • 1. Re: Another query question
          alwu-Oracle
          You can use either
          - Oracle Jena Adaptor to run a SPARQL describe, or
          - SQL to turn a row of bound values into multiple triples.
          • 2. Re: Another query question
            user625573
            OK. The Jena Adaptor option means that the result has to be processed on the client side. It would be very useful if the result of a query could be processed entirely in the database, e.g. for inserting into another model, as part of a stored procedure. Is this functionality that may be added in the future? I would have guessed that when you have the machinery to execute the query itself, providing the results in a different form should be relatively simple?

            As for the SQL option, it seems to me that it would be quite difficult to write SQL to turn an arbitrary table of query result into the corresponding triples. For example, how would parts of a query that are not named variables (such as constant terms) be incorporated? I'm not sure you could do this without parsing the query pattern - but please correct me if I'm wrong!

            Regards,
            Jan
            • 3. Re: Another query question
              alwu-Oracle
              Let me show the idea with an extremely simple example.

              Here is a simple SEM_MATCH query

              select x, name from table(sem_match(
              '(?x foaf:name ?name)',
              sem_models('test'),
              null,
              sem_aliases( sem_alias('foaf', 'http://xmlns.com/foaf/0.1/')),
              null))
              ;

              Assume we want to build a graph based on (x, name) pairs. The following query has a constant as part of the select clause.

              select x, 'http://test.org/hasGivenName', name from table(sem_match(
              '(?x foaf:name ?name)',
              sem_models('test'),
              null,
              sem_aliases( sem_alias('foaf', 'http://xmlns.com/foaf/0.1/')),
              null))
              ;
              • 4. Re: Another query question
                user625573
                I see what you're saying. In your example, you're actually changing the predicate so I guess it's more like a SPARQL CONSTRUCT rather than a DESCRIBE query, but that's a minor point.

                This gets harder with a real query where the matched subgraph contains multiple triples though. E.g. if your query was:

                (?x foaf:name ?xname)
                (?x foaf:mailbox ?mbox_x)
                (?x foaf:knowsOfProfessionally ?y)
                (?y foaf:name ?yname)
                (?x foaf:mailbox ?mbox_y)

                In order for the query to return a single set of triples, I guess the select query would have to consist of a sequence of unions of select statements on the result from sem_match. Is there a way this could be done in a single query without repeating the sem_match query hence incurring an efficiency overhead?

                It also means that the structure of the select query has to duplicate the structure of the sem_match query, which obviously makes the query very verbose and cumbersome to write...

                Jan
                • 5. Re: Another query question
                  alwu-Oracle
                  You can use either UNPIVOT or something like this.

                  Assume you have three variables x, y, z coming out of a SEM_MATCH query.
                  Assume you want to generate a separate triple for each variable binding.

                  with three as (select 1 key from dual union all
                  select 2 key from dual union all
                  select 3 key from dual)
                  select decode(key, 1, x || ' rdf:type http://ClassX',
                  decode(key, 2, y || ' rdf:type http://ClassY',
                  decode(key, 3, z || ' rdf:type http://ClassZ', null)))
                  from ( <YOUR_SEM_MATCH_QUERY_HERE>),
                  three
                  ;

                  The above query will output something like

                  http://x rdf:type http://ClassX
                  http://y rdf:type http://ClassY
                  http://z rdf:type http://ClassZ

                  Basically the above query joins a SEM_MATCH query result with a dummy table
                  containing three rows {1, 2, 3}. Decode is then used to output different triples based
                  on different variables.

                  Actually, this technique has nothing special to do with SEM_MATCH. The following example shows another application.

                  with three as (select 1 key from dual union all
                  select 2 key from dual union all
                  select 3 key from dual)
                  select decode(key, 1, x || ' rdf:type http://ClassX',
                  decode(key, 2, y || ' rdf:type http://ClassY',
                  decode(key, 3, z || ' rdf:type http://ClassZ', null)))
                  from (select 'http://x' x, 'http://y' y, 'http://z' z from dual) my_table,
                  three
                  ;