Query linked properties

From semantic-mediawiki.org
Semantic extension(s): Semantic MediaWiki
Further extension(s):  -/-
Keyword(s):  -/-

Description:

This tip will not work with properties that have commas in them.

Let's take an example from this wiki: each site has a list of properties - URL, administrator, extensions used, etc. You would like to have a query that displays all of those, but in addition, also displays a property of a property: the cities in which the administrators live. Ideally, you would like to just run a query like:

{{#ask:[[Category:Sites]]
|? Has URL
...
|? Has administrator.Has city
...
}}

...however, for performance reasons, SMW doesn't support the display of linked properties in queries - you can filter on them (e.g., [[Has administrator.Has city::Boston]]), but you can't display them for each page.

The solution is somewhat convoluted, but it works. The page for each site can query for the set of administrator cities, then apply a property like "Has city administrator" onto each, using a combination of #ask and #arraymap (the latter is defined in Page Forms (formerly Semantic Forms), which you would need).

The original query could then look like:

{{#ask:[[Category:Sites]]
...
|? Has administrator city
...
}}

This is in fact implemented on this wiki. Here is the code within Template:Site that does it for each site:

{{#arraymap:
{{#arraymap:
{{#ask:[[{{PAGENAME}}]]|?Has administrator=|link=none}}
|,|x|{{#ask:[[x]]|?Has city=}} }}
|,|x|[[Has administrator city::x| ]]|}}

This is somewhat complex - two #ask calls within an #arraymap, within another #arraymap. Here's how it works: the first #ask query gets the list of administrators for the current site. The inner #arraymap then takes in that list of administrators, and applies a second #ask query on it to get the city (or, theoretically, cities) for each. This produces a list of cities, separated by commas. The outer #arraymap call then takes in this list of cities, and calls the "Has administrator city" onto each one.

Unfortunately, if any of the values for your two properties (in this case, "Has administrator" and "Has city") contain commas, and you expect to have multiple values at least some of the time (i.e., a site can have multiple administrators), you're out of luck - currently, #ask always uses a comma to separate between multiple values, and #arraymap can't distinguish between those commas and commas within actual page names.

That means that this trick will not work with multiple properties (separated by commas) or geographic coordinate properties that contain commas in the format "Latitude, Longitude" as used in Semantic Maps.

Below is the call to just such a query, though with an extra filter to only show those sites that have a value at all. Note the value for "Viget, a Grand Rapids wiki"; proving that multiple cities can be displayed.