3

I am converting user-defined-queries into SPARQL. For example, when user says, "abc", it means give me all nodes of a given type which have some attribute named "abc". As an extension of this, if user says, "abc or (pqr and lmn)", I need to find all nodes of a given type for which some attribute is "abc or (pqr and lmn)". Following is the query I have come up with:

SELECT DISTINCT ?node, ?type                                                 
WHERE                                                                          
{
  {                                                                              
    ?node a ?type .                                                          
    FILTER ( ?type != <sometype>)
  }
{           
  {                                                                              
    ?node ?reln0 ?obj0 .                                                     
    FILTER ( regex(str(?obj0), 'abc', "i") )                           
  }                                                                              
  UNION                                                                          
  {                                                                              
    {                                                                              
      ?node ?reln1 ?obj1 .                                                     
      FILTER ( regex(str(?obj1), 'pqr', "i") )                                
    }
    {                                                                             
      ?node ?reln2 ?obj2 .                                                     
      FILTER ( regex(str(?obj2), 'lmn', "i") )                               
    }                                                                              
  }
}                                                                              
}                                                                              
ORDER BY ?node

But it doesn't return proper results. Is there something wrong with the above given query? I don't want to use the following because I need to generate the conditions dynamically and each clause needs to be separate.

FILTER (regex(str(?obj2), 'abc', "i") || regex(str(?obj2), 'pqr', "i") && regex(str(?obj2), 'lmn', "i"))
Joshua Taylor
  • 80,876
  • 9
  • 135
  • 306
Ksh Padalkar
  • 241
  • 2
  • 7
  • I don't understand why you don't use the second approach with one big `FILTER`. It's simpler and it works. – cygri Apr 13 '12 at 20:49
  • each of the terms can be more complex making the body of the {} bigger and those will be mixed with these basic cases. FILTER works for only this case. – Ksh Padalkar Apr 13 '12 at 23:26
  • Also, I found above query not work on Redland. Then I tried installing ARQ and it worked on it. So, it may be related to that particular implementation. – Ksh Padalkar Apr 13 '12 at 23:28
  • What do you mean by "doesn't return proper results"? – Ben Companjen Mar 28 '13 at 18:34
  • What version of the Redland libraries (and of ARQ) did you use? The results I got seemed to be “proper”. Can you show us any of the data you were working with? – Joshua Taylor Jun 29 '13 at 15:17

1 Answers1

2

I made your query concrete as follows (putting in a definite type for the first filter):

PREFIX : <http://example.org/>

SELECT DISTINCT ?node ?type                                                 
WHERE                                                                          
{
    {                                                                              
        ?node a ?type .                                                          
        FILTER ( ?type != :Type1 )
    }
    {           
        {                                                                              
            ?node ?reln0 ?obj0 .                                                     
            FILTER ( regex(str(?obj0), 'abc', "i") )                           
        }                                                                              
        UNION                                                                          
        {                                                                              
            {                                                                              
                ?node ?reln1 ?obj1 .                                                     
                FILTER ( regex(str(?obj1), 'pqr', "i") )                                
            }
            {                                                                             
                ?node ?reln2 ?obj2 .                                                     
                FILTER ( regex(str(?obj2), 'lmn', "i") )                               
            }                                                                              
        }
    }                                                                              
}                                                                              
ORDER BY ?node

I then generated the following data:

@prefix : <http://example.org/> .

:n1 a :Type2 ;    # keep
    :r0 :NodeABC .

:n2 a :Type2 ;
    :r0 :NodeBCD .

:n3 a :Type2 ;     # keep
    :r1 :NodePQR ;
    :r2 :NodeLMN .

:n4 a :Type2 ;
    :r1 :NodeQRS ;
    :r2 :NodeLMN .

:n5 a :Type2 ;
    :r1 :NodePQR ;
    :r2 :NodeMNO .

:n6 a :Type2 ;
    :r1 :NodeQRS ;
    :r2 :NodeMNO .

Only :n1 and :n3 should be kept. I can run this with Jena's command line ARQ, or the Redland based roqet, and I get these rules in both cases.

With ARQ:

$ arq --data data.n3 --query query.sparql
-----------------
| node | type   |
=================
| :n1  | :Type2 |
| :n3  | :Type2 |
-----------------

$ arq --version
Jena:       VERSION: 2.10.0
Jena:       BUILD_DATE: 2013-02-20T12:04:26+0000
ARQ:        VERSION: 2.10.0
ARQ:        BUILD_DATE: 2013-02-20T12:04:26+0000

With roqet:

$ roqet query.sparql -D data.n3 -r table
roqet: Querying from file query.sparql
--------------------------------------------------------------
| node                       | type                          |
==============================================================
| uri<http://example.org/n1> | uri<http://example.org/Type2> |
| uri<http://example.org/n3> | uri<http://example.org/Type2> |
--------------------------------------------------------------

$ roqet -v
0.9.28
Joshua Taylor
  • 80,876
  • 9
  • 135
  • 306