Setting up query to pull multiple items

Question. What woudl be a better way to construct this query:

descendedFrom("The Book")&$Type=="Chapter"|$Type=="Map"|$Type=="Dance"|$Type=="Image"|$Type=="Opera"|$Type=="Prophecy"|$Type=="Song"|$Type=="Story"|$Type=="Vision"|$Type=="Sheet of Purple Paper"`

I’d love to do something like descendedFrom("The Book")&$Type.icontaints($MySet(agent)) and the agents $Type=Chapter;Dance;Image;Map;Opera;Prophecy;Sheet of Purple Paper;Song;Story;Vision. This however, returns everything in the The Book. I’m not exactly sure how to do this.

First, you want to use parentheses to be sure Tinderbox understands your intent:

descendedFrom("The Book")& ($Type=="Chapter"|$Type=="Map"|$Type=="Dance")

I think, with no parentheses, this is interpreted as

((descendedFrom("The Book")& $Type=="Chapter") |$Type=="Map")|$Type=="Dance")

But I’m not sure.

The test you want might be $MySet(agent).contains($Type). Not that above you wrote icontaints.

I’ve dealt with similar before via a user boolean. For instance we add $Grp1Bln (‘1’ as we might have several such groups), remembering to add a description for the new attr as to its purpose.

Now, for all 10 prototype’s set:

$Grp1Bln = true;

Now your query is:

descendedFrom("The Book") & $Grp1Bln
// or in longer form
descendedFrom("The Book") & $Grp1Bln==true

It doesn’t matter that other notes using these prototypes also have $Grp1Bln set via the prototype as the opening query term narrows the scope of testing of the second term.

I should add this mechanism wants consideration within your doc(s) search strategies—do take a moment to consider if usage like above might create edge cases.

A nice aspect to this approach, i.e. where we set a flag representing many possible filtering matches, is that it can play nicely with careful prototype use. Thus prototype “Map” might be true for $Grp1Bln, $Grp2Bln , and $Grp3Bln whereas prototype “Dance” might only have a flag set for $Grp3Bln.

Essentially you are making ad hoc lists of prototypes identified for search via a user boolean.


I’ll look at adding something to the docs on agent queries to reflect the last above. I think it useful for the user (unless very export with boolean search logic) to be explicit with OR (|) joins by placing the OR elements—two or more |-joined terms within parentheses as above. Thankfully such signalling of intent is no direct with doing the same in Excel, a process to which pretty much all users will have had exposure so making it more easily learned/applied.

I have a note in using parentheses in action code but not, more specifically, about their use in queries. I’ll rectify that.

†. Other spreadsheets are available. :wink:

Hi MarkA

In the above example, are you “chaining prototypes” as described here: Chaining prototypes . I am slightly unclear by what I think you mean by grouping protytypes using the UA $Grip1Bln $Grp2Bln etc

Thanks
Tom

Chaining? No. Chaining is where prototype itself uses a prototype (and so on if needed). IOW, in that context one prototype is itself inheriting value(s) from another prototype. It’s rarely needed but has uses as explained in Chaining prototypes.

Here we are doing something different. Don’t get too caught up on the attribute names i used. Too avoid a long post, I omitted more detail. But if goes like this…

  • The ‘Bln’ part of the attr name reminds me, the user (i.e. ‘future self’!), is it a Boolean type.
  • The “Grp” part is short for “(search) Group”, but again you can use what you like.
  • The “1” part is me thinking ahead, I might well have several of these search groups so this saves me renaming the attribute if I add a second or subsequent group. From time spent working with @satikusala on his report process, I’ d wager it’s almost a certainty here. I prefer numbering that goes 1-2-3 as opposed to [nothing]-2-3; not least, sorting works better.

So what, here is a ‘search’ group. Well in the opening case the query wanted to test ten discrete attributes. as a result that was 10 equality tests written out in full. Plenty of scope for mis-keying plus hard to read in the Ui as the query is so long. The ‘trick’ here is, for only those 10 prototypes, to set the user attribute $BlnGrp1 to true. Thus this short query:

descendedFrom("The Book") & $BlnGrp1==true

is the functional equivalent or and can replace the original long query:

descendedFrom("The Book") & ($Type=="Chapter"|$Type=="Map"|$Type=="Dance"|$Type=="Image"|$Type=="Opera"|$Type=="Prophecy"|$Type=="Song"|$Type=="Story"|$Type=="Vision"|$Type=="Sheet of Purple Paper")

It also gets around the issue of where/whether additional structuring parentheses are needed to ensure the query is parsed correctly.

The other aspect (behind the last bullet point), is that in a complex project you might need to do several of these queries involving different combinations of prototypes. As each attribute is discrete, each prototype can have differing true/false values for each search group boolean.

I’ve done a minimal demo here. The items in the “Unwanted” container use prototypes that have search group boolean values but as per the use case above we don’t want them matching or agents (IOW we should see only notes Winken, Blinken, or Nod but never Foo, Bar, or Baz.

The first agent’s query is:

descendedFrom("Wanted")&$BlnGrp1==true

and the other two simply change the tested search group. the final agent uses:

descendedFrom("Wanted")&$BlnGrp1==true&$BlnGrp3==true

Here is the test doc for the above: search-groups.tbx (107.0 KB)

As a footnote, I’d ask the reader here not to be too literal. This is a pattern for use. The user attribute needs to be a boolean but the exact name is up to you and your naming style. Similarly, this uses the boolean attribute allied with prototypes because that is the original scenario at start of the thread. But it doesn’t have to be set via a prototype. For instance, it might be set on particular notes with specific value(s) in specific attribute(s). So, apply this as a pattern of usage rather than a model to be executed to the exact letter of the original sample

Hopefully, this removes some earlier ambiguities.


†. Actually, following my normal aTbRef naming conventions “IsGrp1” might have been a better choice. But, this helps make the point that you should use user attribute names that make sense to you even if no other user. This is even mote the case if replicating someone else’s solution in your own doc, though remember to also update attribute names in any copy/pasted code§. The attribute naming style can help your future self, returning later to the work, to grasp quickly the intent of the attribute whilst the attribute’s description—(you did remember add one? :wink: )—will give you more detail as needed.

‡. This demo doc also shows the importance, when adding test data, of having sufficient data to test both what should be found and what should not be found. Were one of the agents to match ‘Foo’ it would indicate an error in our logic planning.

§. That might seem a chore but it is actually good as it means you have to (skim) read the code giving you a chance to comprehend some or all of what is being done. Free leaning!

1 Like

ok, thanks MarkA. $BlnGrp#'s are boolean User Attributes you have set in the prototypes. Many thanks for the example. It clarified my understanding.

Tom

1 Like

Awesome. I used $IsNoChapterNo as my boolean. I too use a patter for booleans, IsYes… IsNo… which helps my logic. In this case I used the negative test $IsNoChapterNo==true, i.e. ignore those notes that I don’t want to include in the chapter numbering scheme. Worked perfectly!