Global search doesn't work properly for ancestor and parent operators

Steps to reproduce + Expected result +Actual result

Global search doesn’t work properly with ancestor, parent`

I was working with a global search and tried to use operators described here:


And found a few bugs

I have next folder structure

Folder structure:

Wonderful // folder
  - Amazing document // document
    - #must                   //items in a document
      - do something
  - Independent // document
    - #must                   //items in a document
      - do something

:white_check_mark: If search for Amazing document or "Amazing document"
Search give me matched document

:negative_squared_cross_mark: But if I try to search for a #must within Amazing document with:
Amazing document #must, "Amazing document" #must, Amazing #must
Search don’t give me any matches

:negative_squared_cross_mark: If I search for page with ancestor: or parent:
ancestor:Amazing document, ancestor:"Amazing document", parent:Amazing document, parent:"Amazing document"
Search don’t give me any matches

:negative_squared_cross_mark: If I search for #must within Amazing document:
ancestor:Amazing document #must, ancestor:"Amazing document" #must, parent:Amazing document #must, parent:"Amazing document" #must
Search don’t give me any matches

:white_check_mark: But if I use only Amazing from Amazing document to search:
ancestor:Amazing parent:Amazing
Search give me matched items withing Amazing document

:negative_squared_cross_mark: If I do the same but with "":
ancestor:"Amazing" parent:"Amazing"
Search don’t give me any matches

:white_check_mark: When I search for s #must with only Amazing from Amazing document
ancestor:Amazing #must, parent:Amazing #must
Search give me matched items

:negative_squared_cross_mark: If I do the same but with "":
ancestor:"Amazing" #must, parent:"Amazing" #must
Search don’t give me any matches

:negative_squared_cross_mark: If I what to find a #must within a Wonderful folder
Wonderful #must, ancestor:Wonderful #must
Search don’t give me any matches

:negative_squared_cross_mark: If I what to find Amazing document or just Amazing withing Wonderful folder:
Wonderful Amazing document, Wonderful Amazing
ancestor:Wonderful Amazing document, parent:Wonderful Amazing document
ancestor:Wonderful Amazing, parent:Wonderful Amazing
Search don’t give me any matches

:negative_squared_cross_mark: if I search for a few documents:
ancestor:Amazing document OR Independent
Gives matches only for Independent

As I can guess:

  • ancestor: and parent: may not match for Folders
  • ancestor: and parent: may not use " " operator
  • ancestor: and parent: may not use a OR b operator

Environment

Which operating system are you using?
Ubuntu 18.04, Windows 10
Which browser are you using?
Chrome 80
Are you using any third-party scripts for Dynalist, e.g. PowerPack?
No

Thanks for the extensive testing! I believe currently the search option does not affect folders, and quotations are not recognized. The search algorithm can basically be boiled down to:

  • Split entire search by “_OR_” where “_” denotes a space character. If any of the separate pieces results in a match, the query is considered matched.
  • For each piece of the OR query, split by the space character. If all of the the separate pieces results in a match, the query is considered matched.
  • For each piece of the AND query (split by space character), if it starts with any of the special formats such as “ancestor:” or “parent:”, they are considered special queries, otherwise they are to be string-matched.
  • For every node (item) in the document, match it through the parsed search query. If it results in a match show it.
  • “ancestor:” and “parent:” queries does an extra step to fetch the parent node (or iterate through parent chain) of the currently matching node for an exact string match (case insensitive). The implementation can be thought of content.toLowercase().contains(query.toLowercase()).

I would move this to feature requests with suggestions for improvement to the following:

  • Parse quotations for “special:” search parameters, to allow queries with spaces such as ancestor:“word1 word2”.
  • Add some way to search the folder/document structure for global searches.

Do you think these would solve your use-case?

@Shida Hi!

I’m not sure that it’ll fully fix the issue.

So with your addition that query like:

ancestor:"One Other" OR Third #must

will work, So you’ll parse it like:

option | ancestor: ["One Other" OR Third]
text | [#must]

But in case of query like:

ancestor:One Other OR Third #must

We won’t properly recognize the pattern

I’d expect to have

option |  ancestor: [One AND Other OR Third`]
text | [#must]

But what I’ll get:

option |  ancestor: [One]
text | [Other OR Third AND #must]

Or another example

ancestor:One OR Third #must

I will look valid for both

option: | ancestor: [One OR Third]
text | [#must]

and

option: | ancestor: [One]
OR
text | [Third AND #must]

So this example even harder for user.
You’d expect:

  • ancestor: to be one or another?
  • ancestor: OR another text ?

So what I can suggest if we’ll add some way how to indicate that a query after option: is a complex one?

For example like (any of this):

ancestor:'One Other OR Third' #must  // this is not preferable since ' - is widely used in words
ancestor:{One Other OR Third} #must
ancestor:[One Other OR Third] #must
ancestor:`One Other OR Third` #must
ancestor:One Other OR Third: #must  // this is not preferable since : - is widely used in words

In this case you can match

  • if anything after option: start with <indicator>, just get it everything until next <indicator> and parse as string with regular rules for a string (but without other options:).
  • If it’s not, just take everything before next _ (space character)

It shouldn’t brake any existing user queries and will allow to have much cleaner syntax for users.

How it sound to you?

Hmm I’m not sure we’re understanding the same thing with how the OR works.
The OR splitting is done first, so ancestor:"One Other" OR Third #must will be split in:

option | ancestor: [“One Other”]
OR
text | [Third] AND text | [#must]

ancestor:One Other OR Third #must would be

option | ancestor: [One] AND text | [Other]
OR
text | [Third] AND text | [#must]

Without the quotation parsing, you can still do “ancestor:One ancestor:Other” which is a bit clumsy but gets the job done as a workaround.

@Shida That is a nice trick tho.

But still what I have folder structure like

Awesome folder
 - Really interesting Document
   - #must do some
 - Really important Document 
    - #must do some

Would I be able to do ancestor:Really Document #must ?

Here we’re missing something.

If what to much in a document like Really Document which should match both Really interesting Document and Really important Document
I can’t use "Really Document" since it won’t match at all.
So if’ll do ancestor:Really Document #must

While I want to have:

option | ancestor: [Really AND  Document]
OR
text | [#must]

But what I’ll get in practice?

option | ancestor: [Really AND  Document AND #must]
OR
text | []

or

option | ancestor: [Really]
OR
text | [Document AND #must]

What I want to say that it’s not clear way to understand where is the <query> in ancestor:<query> is finished.

It not about current code implementation (it’ls a thousands ways to parse it with a JS)
I what to talk more about how to make it easy to use and understand from user perspective.

I understand. I think in that case having two different ancestor: clauses would be the most unambiguous way. It’s more friction for the user for sure, but it would behave consistently in a way you’d expect it to work.