bwanders / dokuwiki-strata

Strata - a Semi-Structured Data plugin for Dokuwiki
https://www.dokuwiki.org/plugin:strata
17 stars 8 forks source link

Example query: if defined, then [filter]? #12

Closed simon-r-white closed 9 years ago

simon-r-white commented 9 years ago

I have an object that can be defined or not, eg.

<data MISC>
Name: Bob
Count: 3
</data>

<data MISC>
Name: Bill
Count: 
</data>

<data MISC>
Name: Ben
Count: 15
</data>

Following from the Public Examples issue, I'd like to generate a table with all data entries that either: (a) have no Count defined, or (b) if it is defined is must be greater than 10.

Neither of the following do what I want

<table ?name ?count>
?name is a: MISC
optional {
  ?name Count: ?count
  ?count > 10
}
</table>

<table ?name ?count>
?name is a: MISC
optional {
  ?name Count: ?count
}
minus {
  ?name Count: ?count2
  ?count2 > 10
}
</table>

I'd like a table include Bill (Count is undefined) and Ben (Count is defined AND greater than 10), while excluding Bob (Count is defined BUT less than or equal to 10)

I just can't quite work out the combination of optional/minus/etc blocks to achieve this.

bwanders commented 9 years ago

What you try to do is combining two sets of results: those that have no count, and those that have count > 10. This is a job for the union construct, whose sole purpose is merging two or more results into the query.

<table ?name ?count>
?name is a: MISC

union {
  {
    -- we need the next line to have '?name' within scope
    ?name is a: MISC
    minus {
      ?name Count: ?count
    }
  }
  {
    ?name Count: ?count
    ?count > 10
  }
}
</table>
bwanders commented 9 years ago

Feel free to close this issue if that worked.

simon-r-white commented 9 years ago

I see. Yeah that makes sense now... I must confess I didn't really see what the union construct was for, but now you mention that it makes sense.

I also realised a minor mistake in my example... if all three data entries are on the same page without fragment identifiers it goes a bit wrong.

As a more complete example (in case future readers are interested), the following does what I was asking for:

<data MISC #Bob>
Name: Bob Ross
Count: 3
</data>

<data MISC #Bill>
Name: Bill JJ
Count: 
</data>

<data MISC #Ben>
Name: Ben Ten
Count: 15
</data>

<table ?item ?name ?count>
union {
  {
    -- we need the next line to have '?name' within scope
    ?item is a: MISC
    ?item Name: ?name
    minus {
      ?item Count: ?count
    }
  }
  {
    ?item is a: MISC
    ?item Name: ?name
    ?item Count: ?count
    ?count > 10
  }
}
</table>

In words, table the union of two searches: (i) all items of type MISC with a Name field AND remove (aka minus) all results with a Count field defined; and (ii) all items of type MISC with a Name field and Count field > 10.

Also, after having a bit of a play, I think the following achieves the same thing:

<table ?item ?name ?count>
?item is a: MISC
?item Name: ?name
optional {
  ?item Count: ?count
}
minus {
  ?item Count: ?count2
  ?count2 <= 10
}
</table>

In words, table all items of type MISC with a Name field AND optionally a Count field AND remove (aka minus) all items with a defined Count field <= 10.

I think the above two tables are equivalent... with the difference being how we minus (aka remove) returned items.

There's a lot of power in the strata-plugin, I'm beginning to put multiple data entries on my wiki pages and using the table has a sort of indexing/contents.

bwanders commented 9 years ago

Glad you find it useful!

I'd also like to thank you for bringing these points to github. Having a record of how someone discovers the use of the plugin will be of great help when I finally have time to update the documentation.

simon-r-white commented 9 years ago

Thank you for taking the time to answer my questions.