How to do a nested query?

(Rene Trappel) #1

I’ve “exploded” (Note > Explode…) very long documents ($Prototype=*dokument) into hundreds of smaller notes, which are stored as children ($Prototype=*dokument-fragment) in the container of the original note. I now want to do a query only on children whose parents meet a specific criteria:

$Prototype=="*dokument" & $Text.icontains(“Term”)

In other words, I’m trying to do a nested query :slight_smile:

Thanks for any suggestion on how to do this.

(Mark Anderson) #2

Have you tried:

$Prototype(parent(original))=="*dokument" & $Text.icontains("Term")

Or, why not set a new prototype, for example *fragment, for all the exploded notes then use:

$Prototype=="*fragment" & $Text.icontains("Term")

(Rene Trappel) #3

Thanks for the quick reply! I did set a prototype for the exploded notes (*dokument-fragment). But I literally have thousands of notes of this prototype and only want to see those whose parent document has a particular phrase (I’m looking at Chinese policy documents, the phrase I’m looking for is only mentioned since late 2017; about 5-10 container notes, each with about 1-200 exploded notes). However, not all of the exploded notes have this phrase in their $Text. So:

$Prototype=="*dokument-fragment" & $Text.icontains(“Term”)

is not working.

I want to work with all exploded notes in containers that have $Text.icontains(“Term”).

(Mark Anderson) #4

It might just be the auto-substitution of quote characters but your query is:

$Prototype=="*dokument-fragment" & $Text.icontains(“Term”)

This will fail, because of curly quotes. the correct syntax is:

$Prototype=="*dokument-fragment" & $Text.icontains("Term")

Regardless, I don’t see how to (generically) narrow the scope other than to set $MyString in the agent to the name of the exploded note and then use this query:

descendedFrom($MyString(agent)) & $Prototype=="*dokument-fragment" & $Text.icontains("Term")

This way the maximum scope is the contents (descendants) of the container name you set in the agent.

I’m guessing ‘Term’ here is also a placeholder. So, if we define a $MyString2 in the agent we can query:

descendedFrom($MyString(agent)) & $Prototype=="*dokument-fragment" & $Text.icontains($MyString2(agent))

If I’m misunderstanding, my apologies and by all means re-state the question. I do recognise the scenario here, I’m doing similar in my own research.

(Rene Trappel) #5

Thanks again. No, worries about the curly quotes - I had not yet figured out how do code blocks correctly.

I was experimenting with descendedFrom, but have had only limited success. I have not mentioned this yet, but it might be important: I’m trying to achieve this in the Attribute Browser.

So this is the full scenario:

  1. Several container documents (the policy documents) distributed in other container documents (…February 2018, March 2018…) have in their $Text the phrase “乡村振兴”. However, there is no master container with just the exploded notes I’m looking for (following the advice that in TB the location of a note is not that important).

In the AB I use:

$Prototype=="*dokument" & $Text.icontains("乡村振兴")

to find the relevant container documents with the policy documents.

  1. In these containers there are exploded notes for each paragraph, all of them of the prototype “*dokument-fragment”. Some contain the term “乡村振兴”, but most don’t. I want to work with all of these exploded notes with different queries (e.g. $Tag==“agriculture” or $Text.icontains(“xyz”) ).

I thought it would be pretty smart to create an agent with the above query:

$Prototype=="*dokument" & $Text.icontains("乡村振兴")

and then limit the scope of the AB in the container field to that particular agent. Turns out that alias do not have the children of their source note. Is that correct? So this is where I’m stuck at.

(Mark Anderson) #6

Any of:

  • select content and click the ‘</>’ formatting button
  • put a back-tick before after the code .
  • for the coloured version I’ve used, but three back-ticks on a separate line of their own both before and after your code sample.

Your #1 - understood all makes sense. As to #2

Correct. IIRC a query can query the descendants of the aliases original. I’m confused though. The notes you want to match are actually of prototype *dokument-fragment. So surely you meant:

$Prototype=="*dokument-fragment" & $Text.icontains("乡村振兴")

For AB view, make a new tabuse the ‘Container’ pop-up to the container to which you wish to restrict content (i.e. don’t ry to AB view an agent) and then add the above query as the AB view’s query.

Does that help?

(Rene Trappel) #7

I used the version with three back-ticks as in Github Markdown and it worked. With that out of the way:

This is both correct and wrong. I do want to do queries on notes of the type prototype *dokument-fragment but not all of them have $Text.icontains("乡村振兴"), given their nature of being an exploded note. If it would be like this I would just run a query on the whole document looking for $Prototype=="*dokument-fragment" & $Text.icontains("乡村振兴") and there would be no need for a nested query. The confusing part is that only the parent notes (containers) of the type *dokument need to have this phrase for the children to become relevant for my search.

This sounds exactly like what I wanted to do.

(Rene Trappel) #8

Sorry to ask again, but how do I do that in the AB?

(Mark Anderson) #9

I don’t think AB affects this aspect of querying - it’s about scope.

Here are my notes on queries & aliases.

(Pat Maddox) #10

I’m a bit unclear as to what you’re looking for, but you can use an attribute along with a designator:


This will find any note whose parent contains “foo” in the $Name.

So I think you’re looking for:

$Prototype=="*dokument-fragment" & $Text(parent).icontains("乡村振兴")

Example document: parent query.tbx (57.0 KB)

(Rene Trappel) #11

This was exactly what I was looking for, thanks!

Thanks also for this.