bwanders / dokuwiki-strata

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

Can two searches clauses be union'ed? #30

Closed skysgh closed 7 years ago

skysgh commented 7 years ago

Great plugin. Really really useful.

Only have two requests so far.

The first is...how do I combine search clauses to search by Foo or Bar?

skysgh commented 7 years ago

My other question is ...is there a way to format a string with some of the variables? eg: create a tmp variable and output something like the "Refer to \:r for further info."

Again...Great plugin. Really really helping me get organized...

Cheers.

bwanders commented 7 years ago

Glad to hear that you find the plugin useful!

As to the first question "How do I combine search clauses to search by Foo or Bar?"

In the search UI displayed with tables one can only do simple searches, so things like "Foo" or "Bar" are not possible there. In the query format, you can combine search patterns through the use of the union construct:

?s is a: example
union {
  {
    ?s Foo: 10
  }
  {
    ?s Bar: 20
  }
}

Any variables that match inside the union get carried out, so you could have an additional ?s Description: ?desc statement with the Foo and the ?desc would be available to show in the resulting table.

As to the second question "Is there a way to format a string with some of the variables?"

The query system does not allow the construction of temporary variables. That being said, you can do complex formatting by using the bwanders/dokuwiki-plugin-templatery and bwanders/dokuwiki-plugin-stratatemplatery plugins.

The Templatery plugin offers generic templating, and the second combines the data handling of Strata with the templating from Templatery. Their README's should get you going with that.

bwanders commented 7 years ago

(Blegh; hit Close and Comment.)

Do these answers help you out?

skysgh commented 7 years ago

Hi, First off, apologies for the tardy thanks -- end of year madness at work...

Unfortunately, no :-(

Still can't get union to work.

I've tried

union {
{
?tg: [Usability]
}
{
?tg: [UI]
}

And

union {
{
?tg ~ [Usability]
}
{
?tg ~ [UI]
}

And

union {
{
?tg: [Usability]
}
{
?tg: [UI]
}

And without reusing the var I already created

union {
{
?r Tags ~ [Usability]
}
{
?r Tags ~ [UI]
}

...but keep on getting the following.

Unknown triple pattern or filter pattern '?r Tags ~ [Usability]'.

What's the obvious part that I am missing?

As for the templates, can't say I've wrapped my mind around them yet.

Thanks!

bwanders commented 7 years ago

Let's focus on the query first, before getting to the whole template thing.

You are nearly there with the last attempt:

<table ?r>
union {
  {
    ?r Tags: [Usability]
  }
  {
    ?r Tags: [UI]
  }
}
</table>

That nets you all ?r that are tagged with [Usability] or [UI]. The trick is that a Union most contain actual triple patterns, and not only filters:

(This additional information is possibly overkill, but wanted to clarify the difference to be sure.)

Hope that helps!

skysgh commented 7 years ago

Right...

The following works

<list ?r "Id" ?re [wiki] "Requirement"> ?r is a: requirement optional { ?r Tags : ?tg } optional { ?r Requirement [wiki] : ?re } union { { ?r Tags : [UI] } { ?r Tags : [Usability] } } sort { ?r (asc) }

But can a filter be mixed with the predicate somehow?

<list ?r "Id" ?re [wiki] "Requirement"> ?r is a: requirement optional { ?r Tags : ?tg } optional { ?r Requirement [wiki] : ?re } union { { ?r Tags : ~ [UI] } { ?r Tags : ~ [Usability] } } sort { ?r (asc) }

...tricky little syntax...

Sky Sigal : Solution Architect, Ministry of Education, NZ http://skysigal.com : +64 021 159 6440

On Thu, Dec 15, 2016 at 1:39 AM, Brend Wanders notifications@github.com wrote:

Let's focus on the query first, before getting to the whole template thing.

You are nearly there with the last attempt:

<table ?r> union { { ?r Tags: [Usability] } { ?r Tags: [UI] } }

That nets you all ?r that are tagged with [Usability] or [UI]. The trick is that a Union most contain actual triple patterns, and not only filters:

  • A triple pattern is a pattern of ?subject ?predicate: ?object, where you are free to replace any number of the variables with constants... ?r Tags: ?tag is a good pattern, and so is ?r Tags: Usability, or ?r ?relation: UI.
  • A filter is anything like ?var1 ?var2 or ?var1 Constant. With replaced with one of the Comparison Operators section from the manual.

(This additional information is possibly overkill, but wanted to clarify the difference to be sure.)

Hope that helps!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwanders/dokuwiki-strata/issues/30#issuecomment-267023864, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHhJqLg2Soxu05u7Y6JxG2a15BXNtxeks5rH-OAgaJpZM4LJjIM .

bwanders commented 7 years ago

You can't place a pattern and a filter on a single line, but you can add both a pattern and a filter:

<list ?r "Id" ?re [wiki] "Requirement">
  ?r is a: requirement
  optional {
    ?r Tags : ?tg
  }
  optional {
    ?r Requirement [wiki] : ?re
  }
  union {
    {
      ?r Tags : ?temp1
      ?temp1 ~ [UI]
    }
    {
      ?r Tags : ?temp2
      ?temp2 ~ [Usability]
    }
  }
  sort {
    ?r (asc)
  }
</list>

I admit that this isn't the nicest way to express a "match this or that" kind of filter, but there's currently not better way to do it.

You could also ask yourself if it really is the best plan to do "tags contains some string" matching on sets of tags. Maybe we can find a way that better represents the data you are trying to model. Can you give an example of a data block that adds this data?

skysgh commented 7 years ago

Closer! Finally don't have syntax errors. Getting somewhere finally ;-)

But the behaviour is still unexpected. I'm looking to do the equivalent of AND. I'm getting OR from the union statement.

Currently, I'm entering requirements as follows:

<data requirement  #SFREQ-cwlrh>
Guid :

But requirements cover multiple concerns, and I'd like to filter them, using AND statements. Otherwise I'm going to quickly end up with having to create an unwieldy mess of [UI/Validation] tags...which probably won't fly.

Cheers!

PS: As for why I'm using square brackets around tags, is so I could filter for [UI] -- and not pick up words that have 'ui' in it ...

PPS: Still..warts, bizarre syntax, and all...it's still the best system available in Dokuwiki, by a mile. Totally right approach using the dokuwiki pages as source, and searchable db as cache. Nice.

Sky Sigal : Solution Architect, Ministry of Education, NZ http://skysigal.com : +64 021 159 6440

On Fri, Dec 16, 2016 at 12:04 AM, Brend Wanders notifications@github.com wrote:

You can't place a pattern and a filter on a single line, but you can add both a pattern and a filter:

<list ?r "Id" ?re [wiki] "Requirement"> ?r is a: requirement optional { ?r Tags : ?tg } optional { ?r Requirement [wiki] : ?re } union { { ?r Tags : ?temp1 ?temp1 ~ [UI] } { ?r Tags : ?temp2 ?temp2 ~ [Usability] } } sort { ?r (asc) }

I admit that this isn't the nicest way to express a "match this or that" kind of filter, but there's currently not better way to do it.

You could also ask yourself if it really is the best plan to do "tags contains some string" matching on sets of tags. Maybe we can find a way that better represents the data you are trying to model. Can you give an example of a data block that adds this data?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/bwanders/dokuwiki-strata/issues/30#issuecomment-267301034, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHhJjvtMc6450QOqi9O8TjMkLX4HC7Mks5rIR6pgaJpZM4LJjIM .

bwanders commented 7 years ago

(First a short note: If you put your code examples between hedges of ``` they will be set in monospace font, and overall look a tad nicer.)

Ahhh... Now I get it! You want to AND the conditions, instead of having them ORed. Right.

Well, that's brutality simple then. Simply filter on both terms:

<list ?r "Id" ?re [wiki] "Requirement">
  ?r is a: requirement
  ?r Tags : ?tg
  ?tg ~ [UI]
  ?tg ~ [Usability]
  optional {
    ?r Requirement [wiki] : ?re
  }
  sort {
    ?r (asc)
  }
</list>

I dropped the optional from the ?r Tags: ?tg pattern, since any requirements that have a [UI] and [Usability] tag by necessity have data for the Tags field. Then it's a simple matter of declaring that the matched tags should contain both the tags you want.

The best way to understand these queries is by not thinking of them as database queries (in the relational sense), but as describing the pattern you want to match. In this case you want to match all ?r that have some Tags that match two different filters.

Hope this helps!

PS. I'm interested in what you think is a less bizarre syntax for describing the pattern you want to match -- I don't have time to implement it right now, but feel free to open another issue so we can discuss! (I modeled this syntax roughly after SPARQL which is a query language for RDF, which is a very good fit for the data model of Strata)