Skip to content

Latest commit

 

History

History
328 lines (228 loc) · 12.4 KB

search.md

File metadata and controls

328 lines (228 loc) · 12.4 KB

Query Syntax

The search box supports a powerful query language for filtering architecture resources.

Quick Start

Query Description
kubernetes Name contains "kubernetes" (case-insensitive)
TechnologyArtifact: All resources of a specific kind
activity/status == "active" Annotation equals value
scc/loc == 15000 Numeric equality
activity/status? Annotation exists (is set)
! activity/status? Annotation doesn't exist
-> ApplicationInterface Has relation to a kind
text =~ "failover" Any string annotation contains the text

Name Search

Type any word to search by name (case-insensitive regex match):

kubernetes              # name =~ "kubernetes"
name == "MyService"     # exact match
name =~ "repo-.*"       # regex pattern
name != "OldService"    # not equal
name in ("a", "b")      # name is one of several options

Names often contain colons (Archsight:CLI) and so do aliases (ITGS:A001). Typed without spaces they are one word, found by name or alias like any other bare word:

Archsight:CLI           # the resources named Archsight:CLI
ITGS:A001               # the resource with the alias ITGS:A001
ApplicationService:ITGS:A001   # the same, in one kind

Text Search

text searches the content of resources: every string annotation (descriptions, titles, link/*, page content, ...) is checked for the pattern, case-insensitively, like name =~:

text =~ "failover"                  # any annotation mentions failover
text: "failover"                    # the same, short
text =~ /fail(over|back)/i          # regex literal with flags
text(architecture/description) =~ "standby"      # only this annotation
text(link/*, page/content) =~ "PROJ-1234"        # several keys, `*` is any run of characters
ApplicationService: text =~ "failover" & -> ApplicationComponent   # combined with anything else

In a quoted string a backslash only escapes the next character ("\d" is d); write patterns with escapes as /regex/.

A resource matches when one of the checked annotations matches. The MCP query tool shows the annotation and a short snippet around the match for each hit (matched_text). The bare word text is still a name search; text in YAML comments is not searched.

Kind Filter

Prefix your query with Kind: to filter by resource type (a capitalised word that is a kind, followed by a space or nothing; Kind:Name without a space is the kind and a name):

TechnologyArtifact:                              # all of this kind
TechnologyArtifact: activity/status == "active"  # filtered
ApplicationComponent: kubernetes          # combined

You can also query the kind field directly using operators:

kind == "TechnologyArtifact"                                    # exact kind match
kind =~ "Application.*"                                          # regex match on kind
kind in ("TechnologyArtifact", "ApplicationComponent")          # kind is one of list

Annotation Queries

Query annotation values using comparison operators:

Operator Description
== Equals (numeric comparison for numbers)
!= Not equals (numeric comparison for numbers)
=~ Regex match
> Greater than
< Less than
>= Greater or equal
<= Less or equal
in Value is one of several options

Examples:

activity/status == "active"
activity/status != "abandoned"
scc/language/Go/loc > 10000
scc/language/Go/loc == 15000    # exact numeric match
repository/artifacts =~ "container|chart"
repository/artifacts in ("container", "chart")  # matches any listed value

Quoted Annotation Paths

Use single quotes for annotation paths containing special characters (like +):

'scc/language/C++/loc' >= 500
'scc/language/C++/loc'?
activity/status == "active" & 'scc/language/C++ Header/loc' > 100

Attribute Existence

Check if an annotation is set (exists) or not set (doesn't exist) using ?:

activity/status?              # annotation exists
! activity/status?            # annotation doesn't exist
scc/language/Go/loc?          # has Go code metrics

Combined examples:

activity/status? & ! backup/mode?    # has status but no backup
TechnologyArtifact: ! activity/status?  # artifacts without status set

Logical Operators

Combine conditions with logical operators:

Operator Aliases
AND & or and or AND
OR pipe or or or OR
NOT ! or not or NOT

Examples:

activity/status == "active" & repository/artifacts == "container"
repository/artifacts == "container" | repository/artifacts == "chart"
! activity/status == "abandoned"
(a == "1" | b == "2") & c == "3"

Precedence (highest to lowest): Parentheses, NOT, AND, OR

Relation Queries

Find resources by their relationships:

Syntax Description
-> Kind Has direct outgoing relation to kind
-> "Name" Has direct outgoing relation to instance
<- Kind Has direct incoming relation from kind
~> Transitive outgoing (follows chain)
<~ Transitive incoming (follows chain)
-> none Has no outgoing relations
<- none Has no incoming relations

Examples:

-> ApplicationInterface              # exposes an interface
-> "Kubernetes:RestAPI"              # exposes specific interface
<- ApplicationComponent              # referenced by a component
~> MotivationRequirement               # transitively reaches requirement
-> none & <- none                    # orphan (no relations)
TechnologyArtifact: <- none          # unreferenced artifacts

Verb Filters

Filter relations by their verb (relation type) using {verb} syntax:

Include verbs (allowlist):

Syntax Description
-{verb}> Outgoing direct, only follow 'verb' relations
~{verb}> Outgoing transitive, only follow 'verb' relations
<{verb}- Incoming direct, only from 'verb' relations
<{verb}~ Incoming transitive, only from 'verb' relations
-{v1,v2}> Multiple verbs (OR semantics - follow v1 OR v2)

Exclude verbs (denylist):

Syntax Description
-{!verb}> Outgoing direct, follow all EXCEPT 'verb'
~{!verb}> Outgoing transitive, follow all EXCEPT 'verb'
<{!verb}- Incoming direct, all EXCEPT 'verb'
<{!verb}~ Incoming transitive, all EXCEPT 'verb'
-{!v1,v2}> Exclude multiple verbs (exclude v1 AND v2)

Examples:

# Only repos MAINTAINED by team (not contributed)
TechnologyArtifact: -{maintainedBy}> "MyTeam:Team"

# All relations EXCEPT contributedBy
TechnologyArtifact: -{!contributedBy}> "MyTeam:Team"

# Include multiple verbs
TechnologyArtifact: -{maintainedBy,contributedBy}> BusinessActor

# Exclude multiple verbs
TechnologyArtifact: -{!contributedBy,servedBy}> "MyTeam:Team"

# Transitive with verb filter
ApplicationComponent: ~{realizedThrough}> TechnologyArtifact

# Incoming with verb filter
BusinessActor: <{maintainedBy}- TechnologyArtifact

# Combined with sub-queries
TechnologyArtifact: -{maintainedBy}> $(BusinessActor: activity/status == "active")

# Find artifacts with NO maintainedBy relations
TechnologyArtifact: -{maintainedBy}> none

# Pages that mention a component, and the components they depict
ApplicationComponent: <{mentions}- Page
Page: -{depicts}> ApplicationComponent

# Leave the derived relations (links in text, nodes of diagrams) out of a traversal
ApplicationComponent: ~{!mentions,depicts}> TechnologyArtifact

Sub-Query Targets

Use $(expression) to dynamically find relation targets based on a query:

Syntax Description
-> $(expr) Has relation to any resource matching expr
~> $(expr) Transitively reaches any resource matching expr
<- $(expr) Has incoming relation from any resource matching expr
<~ $(expr) Transitively reached by any resource matching expr

Examples:

-> $(kubernetes)                     # relates to something named "kubernetes"
~> $(name == "MyAPI")                # transitively reaches the instance "MyAPI"
<- $(TechnologyArtifact: activity/status == "active")  # referenced by active artifacts
~> $(-> $(foo))                      # nested: reaches something that reaches "foo"

Sub-queries support the full query syntax including kind filters and logical operators.

Searching Wiki Pages

Wiki pages are resources of the kind Page, so everything above applies. Use the Page: prefix to search pages only.

Annotation Content
page/title Title (the name is the file name, so it is often less readable)
page/tags Comma-separated tags
page/status Free text such as rfc, wip, approved
page/author, page/owner Name <email>
page/content The markdown body, without the frontmatter

A bare word (kubernetes) only matches the name. To search the text of pages, match page/content:

Page: page/content =~ "asd"                                   # pages that mention "asd"
Page: name =~ "query" | page/title =~ "query" | page/content =~ "query"
                                                              # name, title or text (what the Pages tab does)
Page: page/content =~ "asd" & page/status == "approved"       # text search plus a filter
Page: page/tags == "howto"                                    # by tag
Page: page/content =~ "```asd"                                # pages that contain a diagram

Regular expressions are case-insensitive. Inside a quoted string a backslash escapes the next character and is dropped, so a regex backslash has to be written twice. That is how a literal [ is matched, for example to find the pages that link to a page (backlinks):

Page: page/content =~ "\\[\\[Writing Pages"                      # pages containing a link to "Writing Pages"

More ways to find pages:

Page: name == "home"          # the home page
PageMenu: <- none             # root menus (menus no other menu contains)
Page: <- none                 # pages that are in no menu (the home page usually is)
PageMenu: -> Page             # menus that contain pages

Over MCP the same queries work with the query tool, see Pages and AI assistants.

Examples

Active containerized services:

TechnologyArtifact: activity/status == "active" & repository/artifacts == "container"

Everything that is on its way out:

lifecycle/status in ("deprecated", "sunset", "end-of-life")

Resources in use (a resource without a status is active, the annotation's default):

lifecycle/status == "active"

What is planned, not yet in use:

lifecycle/status == "planned"

Services exposing APIs:

ApplicationComponent: -> ApplicationInterface

Large Go codebases:

TechnologyArtifact: scc/language/Go/loc > 5000

Resources with compliance chain:

~> MotivationRequirement

Complex query with grouping:

(repository/artifacts == "container" | repository/artifacts == "chart") & activity/status == "active"

Using in to simplify OR conditions:

# These two queries are equivalent:
repository/artifacts == "container" | repository/artifacts == "chart"
repository/artifacts in ("container", "chart")

# Combined with other conditions:
activity/status == "active" & repository/artifacts in ("container", "chart")

Search results

The result page lists the hits with a count per kind. Click a kind to narrow the list; the query stays the same. Every hit also shows its summary attributes: up to three annotations per kind (normal or computed) that the kind definition marks with summary: true, for example the activity status of a repository or the priority of a requirement. Clicking a tag value searches for that value.

The same data is available from the API: GET /api/v1/search?q=... returns by_kind (hits per kind, for all hits of the query) and, for each hit, highlights:

"highlights": [
  { "key": "activity/status", "title": "Activity Status", "value": "active", "format": "tag_word", "type": null }
]

Add kind=TechnologyArtifact to narrow the hits to one kind (total and paging follow, by_kind still counts all hits).