Search code examples
mediawikisemantic-mediawiki

Semantic MediaWiki: How do I make a query for pages with intermediate relationships?


Suppose I would like to link several wiki pages in a "knowledge graph". Let's say, here is a quick list of geographic objects from bigger to smaller, where arrows denote a direct MediaWiki link:

Continent:Europe
^__Country:Netherlands
   ^__City:Amsterdam
      ^__Venue:Heineken Music Hall

The pages above have the following content:

Continent:Europe

{{#set: | self:name = Europe }}
[[Category:Continents]]

Country:Netherlands

{{#set: | ref:continent = Continent:Europe | self:name = Netherlands }}
[[Category:Countries]]

City:Amsterdam

{{#set: | ref:country = Country:Netherlands | self:name = Amsterdam }}
[[Category:Cities]]

Venue:Heineken Music Hall

{{#set: | ref:city = City:Amsterdam | self:name = Heineken Music Hall }}
[[Category:Venues]]

The properties are declared with the following types:

  • self:name: [[has type::text]]
  • ref:continent, ref:country, ref:city: [[has type::page]]

As far as I understand how Semantic MediaWiki works, the #ask function works for one level. Let's say, {{#ask: [[self:name::+]] }} can fetch all 4 pages because all of the pages have the self:name property set. I can also narrow down the search result by filtering out a certain category: {{#ask: [[Category:Venues]] [[ref:city::City:Amsterdam]] }}. This allows to get immediately related pages (and this is easy as the Venue:Heineken Music Hall page is related to the City:Amsterdam page directly).

Now, let's say, I would like to show all venues that are located in Continent:Europe, so Country:Netherlands and City:Amsterdam should be considered implicitly somehow. {{#ask: [[Category:Venues]] [[ref:continent::Continent:Europe]] }} cannot work, because the query combines two properties that never appear together at the same page. So, does Semantic MediaWiki have any query syntax/ability allowing to specify intermediate relationships so it could "crawl" and "inner join" giving all venues in Europe?

Is it possible to query across several pages specifying intermediate relationships somehow? Or is SMW designed for "flat"/tagged relationships only?


Update

I was not very specific about what I want to get. Let's say, you have to describe an event that could be transformed into a human readable form. Currently, in a non-structured wiki, you might use a custom template like similar to this:

{{Event
| date = 2012-12-03
| country = Netherlands
| city = Amsterdam
| venue = Heineken Music Hall
}}

with the following generated result:

The performance on December 3, 2012 took place at Heineken Music Hall in Amsterdam, Netherlands.

What I'm looking for is something that would allow to compose the following template in Semantic MediaWiki:

{{Event
| date = 2012-12-03
| ref:venue = Venue:Heineken Music Hall
}}

Thus the country and the city might be obtained automatically having the relationships defined somehow above, but still giving the result: The performance on ..., Netherlands.


Solution

  • First, colon : seems to be not very safe to use. I have changed it to a space. Second, SMW supports inverse properties and subqueries, thus the following code answers the questions in the core:

    The performance took place at
    {{#ask: [[Category:Venues]] [[Self name::Heineken Music Hall]]}},
    {{#ask: [[Category:Cities]] [[-Ref city::<q>[[Self name::Heineken Music Hall]]</q>]]}},
    {{#ask: [[Category:Countries]] [[-Ref country::<q>[[-Ref city::<q>[[Self name::Heineken Music Hall]]</q>]]</q>]]}},
    {{#ask: [[Category:Continents]] [[-Ref continent::<q>[[-Ref country::<q>[[-Ref city::<q>[[Self name::Heineken Music Hall]]</q>]]</q>]]</q>]]}}
    

    The same but shorter:

    The performance took place at
    {{#ask: [[Category:Venues]] [[Self name::Heineken Music Hall]]}},
    {{#ask: [[Category:Cities]] [[-Ref city.Self name::Heineken Music Hall]]}},
    {{#ask: [[Category:Countries]] [[-Ref country.-Ref city.Self name::Heineken Music Hall}},
    {{#ask: [[Category:Continents]] [[-Ref continent.-Ref country.-Ref city.Self name::Heineken Music Hall}}
    

    The output:

    The performance took place at Heineken Music Hall, Amsterdam, Netherlands, Europe