Re: query RDF dataset

Jitao Yang wrote:
> Another problem is:
> if I add another new book which has no authors to the RDF file like:
> 
> <?xml version="1.0" encoding="utf-8"?>
> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>          xmlns:dc="http://purl.org/dc/elements/1.1/"
>      xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">
>  
>     <rdf:Description rdf:about="http://example.org/BookJava">
>         <vcard:fullname>Book Java</vcard:fullname>
>         <dc:author>
>             <rdf:Description 
> rdf:about="http://example.org/BookJava/authorA">
>                  <dc:fullname>Bob Smith</dc:fullname>
>                  <dc:country>Italy</dc:country>
>              </rdf:Description>
>         </dc:author>       
>         <dc:author>
>             <rdf:Description 
> rdf:about="http://example.org/BookJava/authorB">
>                  <dc:fullname>Tom Bush</dc:fullname>
>                  <dc:country>Italy</dc:country>
>             </rdf:Description>
>         </dc:author>
>     </rdf:Description>
> 
>     <rdf:Description rdf:about="http://example.org/BookCpp">
>         <vcard:fullname>Book Cpp</vcard:fullname>
>         <dc:author>
>             <rdf:Description rdf:about="http://example.org/BookCpp/author2">
>                  <dc:fullname>Mike Luck</dc:fullname>
>                  <dc:country>France</dc:country>
>             </rdf:Description>
>         </dc:author>
>         <dc:author>
>             <rdf:Description rdf:about="http://example.org/BookCpp/author1">
>                  <dc:fullname>Alice Bird</dc:fullname>
>                  <dc:country>Italy</dc:country>
>             </rdf:Description>
>         </dc:author>   
>         <dc:author>
>             <rdf:Description 
> rdf:about="http://example.org/BookJava/authorB">
>                  <dc:fullname>kobe Mc</dc:fullname>
>                  <dc:country>Italy</dc:country>
>              </rdf:Description>
>         </dc:author>
>     </rdf:Description>
> 
>     <rdf:Description rdf:about="http://example.org/BookC">
>         <vcard:fullname>Book C</vcard:fullname>
>     </rdf:Description>
> 
> </rdf:RDF>
> 
> I want to query "the books whose authors are all Italian" or "the books 
> which have no authors",
> so I use SPARQL like:
> 
>             PREFIX dc:<http://purl.org/dc/elements/1.1/>
>             PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
>             SELECT DISTINCT ?bookName
>             WHERE {
>                     ?bookURI vcard:fullname ?bookName .
>                     OPTIONAL{
>                             ?bookURI dc:author ?author .
>                             ?author dc:country ?country .
>                             FILTER(?country = \"Italy\") .
>                             OPTIONAL{
>                                     ?bookURI dc:author ?author2 .
>                                     ?author2 dc:country ?country2 .
>                                     FILTER(?country2 != \"Italy\")
>                                     }
>                             FILTER(bound(?country2))
>                             }
>                     FILTER(!bound(?author))
>                   }
> 
> I can get the right answers:
> ---------------
> | bookName    |
> ===============
> | "Book C"    |
> | "Book Java" |
> ---------------
> but, my original idea is FILTER(!bound(?country2)) which means filter 
> the books which have non-Italian authors,
> however if I use  FILTER(!bound(?country2)), it will return the opposite 
> answers:
> --------------
> | bookName   |
> ==============
> | "Book C"   |
> | "Book Cpp" |
> --------------
> I can not understand the reasons?
> 
> Thank you very much if Lee would like to explain to me,
> or the other persons who have time to help me?

Because of the !bound(?author), you're only going to receive books that 
don't satisfy your outer optional. Because the outer optional requires 
an author, this will include books with no author, as you want.

Books with an author will only satisfy the outer optional if 
bound(?country2) is true, which is true only if the book has a 
non-Italian author. So you end up excluding those as well, as you want.

That said, I think you've made the query overly complicated. Would this 
accomplish what you want?

             PREFIX dc:<http://purl.org/dc/elements/1.1/>
             PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
             SELECT DISTINCT ?bookName
             WHERE {
                     ?bookURI vcard:fullname ?bookName .
                     OPTIONAL{
                             ?bookURI dc:author ?author .
                             ?author dc:country ?country .
                             FILTER(?country != "Italy") .
                     }
                     FILTER(!bound(?author))
            }

(This is simply the original query but with the part that required at 
least one Italian author removed.)


Lee

> Best wishes,
> Jitao
> 
> On Sat, May 30, 2009 at 21:51, Lee Feigenbaum <lee@thefigtrees.net 
> <mailto:lee@thefigtrees.net>> wrote:
> 
>     Jitao Yang wrote:
> 
>         Dear all,
> 
>         if there is a RDF like:
> 
>         <?xml version="1.0" encoding="utf-8"?>
>         <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>                 xmlns:dc="http://purl.org/dc/elements/1.1/">
>            <rdf:Description rdf:about="http://example.org/BookJava">
>                <dc:fullname>Book Java</dc:fullname>
>                <dc:author>
>                    <rdf:Description
>         rdf:about="http://example.org/BookJava/authorA">
>                         <dc:fullname>Bob Smith</dc:fullname>
>                         <dc:country>Italy</dc:country>
>                    </rdf:Description>
>                </dc:author>              <dc:author>
>                    <rdf:Description
>         rdf:about="http://example.org/BookJava/authorB">
>                         <dc:fullname>Tom Bush</dc:fullname>
>                         <dc:country>Italy</dc:country>
>                    </rdf:Description>
>                </dc:author>
>            </rdf:Description>
> 
>            <rdf:Description rdf:about="http://example.org/BookCpp">
>                <dc:fullname>Book Cpp</dc:fullname>
>                <dc:author>
>                    <rdf:Description
>         rdf:about="http://example.org/BookCpp/author1">
>                         <dc:fullname>Alice Bird</dc:fullname>
>                         <dc:country>Italy</dc:country>
>                    </rdf:Description>
>                </dc:author>          <dc:author>
>                    <rdf:Description
>         rdf:about="http://example.org/BookCpp/author2">
>                         <dc:fullname>Mike Luck</dc:fullname>
>                         <dc:country>France</dc:country>
>                    </rdf:Description>
>                </dc:author>
>            </rdf:Description>
>         </rdf:RDF>
> 
> 
>         and I query the RDF by:
> 
>         PREFIX dc:<http://purl.org/dc/elements/1.1/>
>         SELECT DISTINCT ?bookName
>         WHERE {
>                          ?bookName dc:author ?author .
>                          {?author dc:country ?country . FILTER(?country
>         = "Italy")}
>                      };
> 
>         the query results are:
> 
>         ---------------------------------
>         | bookName                      |
>         =================================
>         | <http://example.org/BookCpp>  |
>         | <http://example.org/BookJava> |
>         ---------------------------------
> 
>         can anybody tell me how to query out the "book whose authors'
>         country are all Italy "?




>         which means the query results should be:
> 
>         ---------------------------------
>         | bookName                      |
>         =================================
>         | <http://example.org/BookJava> |
>         ---------------------------------
> 
> 
>     Jitao,
> 
>     It's not pretty, but you should be able to do it with something like:
> 
>     PREFIX dc:<http://purl.org/dc/elements/1.1/>
>     SELECT DISTINCT ?bookName
>     WHERE {
>      # first, make sure there's an author from italy
>      ?bookName dc:author ?author .
> 
>      ?author dc:country ?country . FILTER(?country = "Italy") .
>      # next, "try" to find another author not from italy
>      OPTIONAL {
>        ?bookName dc:author ?author2 .
>        ?author2 dc:country ?country2 .
>        FILTER(?country2 != "Italy")
>      }
>      # finally, we only want this book if we didn't find any non-Italy
>      # authors
>      FILTER(!bound(?country2))
>     }
> 
>     (Warning, untested query.)
> 
>     hope this helps,
>     Lee
> 
> 
> 
>         Thank you very much for your help!
> 
>         Best wishes,
>         Jitao
> 
> 
> 

Received on Friday, 5 June 2009 16:36:39 UTC