# NQL Overview and Syntax

Refer to the [NQL Quick Reference Guide](/netography-query-language/nql-quick.md) for all the NQL syntax in one table.

## Overview <a href="#overview" id="overview"></a>

The Netography Query Language (NQL) is the basis for accomplishing many tasks in Fusion.

* Searching for flows, DNS, events, audits, or block records
* Filtering statistics and aggregations
* Defining custom Detection Models to create an event

Becoming familiar with NQL will help you take full advantage of the Fusion platform.

{% hint style="info" %}
**📘Comparing NQL to Other Query Languages**

NQL is designed specifically for network traffic and security analytics, with features optimized for querying this type of data. Unlike SQL, which is a general-purpose query language for relational databases, NQL is tailored to operate on high-throughput network data with a focus on real-time analysis. Similar to Splunk's SPL (Search Processing Language) and Elasticsearch's Query DSL, NQL provides specialized operators and pattern matching capabilities, making it well-suited for dynamic network environments. However, NQL's syntax and rules are distinct, reflecting its purpose-built nature for network security operations.
{% endhint %}

## Using NQL in Fusion <a href="#using-nql-in-fusion" id="using-nql-in-fusion"></a>

In the Fusion Portal, NQL can be used In the Global Filter (the bar at the top of the Portal), in Detection Models, or to define widgets inside custom dashboards. It can be used in the API as the value for the `search` parameter if it exists.

### Applying NQL <a href="#applying-nql" id="applying-nql"></a>

Results on each page are filtered by the *Global Filter*, the combination of the date/time range you select and the NQL filter you enter.

{% hint style="info" %}
**📘The button in the Global Filter changes to UPDATE when you need to apply a new value**

If it says **UPDATE**, that means you changed a value but have not yet applied it. Apply the filter by clicking the **UPDATE** button, or pressing Enter in the NQL text box.

<img src="/files/Op9wFohGtT7Ga904iV3X" alt="" data-size="original">
{% endhint %}

## NQL Syntax <a href="#nql-syntax" id="nql-syntax"></a>

### NQL Examples <a href="#nql-examples" id="nql-examples"></a>

Use the [NQL Presets](/netography-query-language/nql-presets.md) to see additional examples.

| Description           | NQL                                                                |
| --------------------- | ------------------------------------------------------------------ |
| IP Reputation Matches | `srciprep.count > 0 OR dstiprep.count > 0`                         |
| Only Privileged Ports | `dstport < 1024`                                                   |
| Not Broadcast IPs     | `dstip != 255.255.255.0/24`                                        |
| TCP Ports Scan        | `tcpflags.syn == true and tcpflags.ack == true and srcport > 1024` |

For additional examples, see [NQL Examples](/netography-query-language/nql-examples.md).

### NQL Basics <a href="#nql-basics" id="nql-basics"></a>

Using the Netography Query Language is like writing a programming conditional inside an `if ( )` statement. The statement should be constructed logically, from left to right, comparing fields to values.

### Rules and Limitations <a href="#rules-and-limitations" id="rules-and-limitations"></a>

#### Spacing and Parentheses <a href="#spacing-and-parentheses" id="spacing-and-parentheses"></a>

* Operators must be surrounded by spaces, e.g. `srcip == 10.0.0.1` is valid, while `srcip==10.0.0.1` is not valid.
* Whitespace is **not optional** in NQL. For example, `input==1` is invalid, but `input == 1` is valid since the NQL parser will not parse the first example if the whitespace is missing.
* NQL accepts nested parentheses. For example, `((this) || (that)) && other` is a valid NQL statement. However, this can be considered hard to read, so it is suggested to reduce the use of parentheses when possible, e.g. `(this || that) && other`
* Logic must be unambiguous. e.g. `A && B || C` will fail. Use parentheses `()` to prevent ambiguity

#### Comparisons <a href="#comparisons" id="comparisons"></a>

* Only integer fields can use numerical comparisons: `< <= > >=`

#### CIDR Notation <a href="#cidr-notation" id="cidr-notation"></a>

* IP fields can be searched with CIDR notation if desired. For example, `10.0.0.0/24` will match `10.0.0.1`

{% hint style="info" %}
**📘CIDR (Classless Inter-Domain Routing)**

CIDR is a method for allocating IP addresses and routing Internet Protocol packets. CIDR uses a suffix (e.g., `/24`) to specify the exact number of bits that represent the network portion of the address. For example, `192.168.0.0/24` defines a network with addresses ranging from `192.168.0.0` to `192.168.0.255`. CIDR is commonly used in routing, firewall rules, and network segmentation to precisely define IP address ranges.
{% endhint %}

### Operators <a href="#operators" id="operators"></a>

{% hint style="info" %}
**❓What is an operator?**

In the context of NQL, operators are used to define how fields should be compared or matched against values, allowing users to filter, search, and analyze data according to specific criteria.
{% endhint %}

### Boolean Operators <a href="#boolean-operators" id="boolean-operators"></a>

| Boolean    | Description                                   | Example                |
| ---------- | --------------------------------------------- | ---------------------- |
| `&&` `AND` | logical AND                                   | `this && that`         |
| `OR`       | logical OR                                    | `this OR that`         |
| `!`        | NOT *must precede expressions in parenthesis* | `!(srcip == 10.0.0.1)` |

### Comparison Operators <a href="#comparison-operators" id="comparison-operators"></a>

| Comparison | Description               |
| ---------- | ------------------------- |
| `==`       | equals                    |
| `!=`       | not equals                |
| `<=`       | less than or equals to    |
| `<=`       | less than                 |
| `>=`       | greater than or equals to |
| `>`        | greater tha               |

For additional examples, see [NQL Examples](/netography-query-language/nql-examples.md).

## Pattern Matching (Wildcards, RegEx, Fuzzy) in NQL <a href="#pattern-matching-wildcards-regex-fuzzy-in-nql" id="pattern-matching-wildcards-regex-fuzzy-in-nql"></a>

In NQL, pattern matching is performed using regular expressions, wildcards, and fuzzy matching. The operators `=~` and `!~` specify these matches and their negative counterparts.

{% hint style="info" %}
**ℹ️NQL fields supporting pattern matching**

Pattern matching is only supported for the fields listed below.
{% endhint %}

| Category | Fields                                                                |
| -------- | --------------------------------------------------------------------- |
| Flow     | `dstiprep.categories srciprep.categories tags`                        |
| DNS      | `answers.rdata query.domain query.host query.name query.publicsuffix` |
| Events   | `ipinfo.iprep.categories summary tags`                                |
| Audit    | `description`                                                         |

### Wildcards <a href="#wildcards" id="wildcards"></a>

Wildcards use special characters to match patterns of text.

#### Wildcards: Operator Syntax and Meaning <a href="#wildcards-operator-syntax-and-meaning" id="wildcards-operator-syntax-and-meaning"></a>

| Operator | Syntax | Meaning                                              | Example Field       |
| -------- | ------ | ---------------------------------------------------- | ------------------- |
| `=~`     | `*at`  | Matches zero or more characters.                     | `query.name =~ *at` |
| `!~`     | `*at`  | Negative match for zero or more characters.          | `query.name !~ *at` |
| `=~`     | `?at`  | Matches any single character before "at".            | `query.name =~ ?at` |
| `!~`     | `?at`  | Negative match for any single character before "at". | `query.name !~ ?at` |

**Note**: Avoid beginning patterns with `*` or `?` as this can lead to performance issues due to increased iterations.

### Regular Expressions (regex) <a href="#regular-expressions-regex" id="regular-expressions-regex"></a>

Regular expressions (regex) allow for flexible and complex search patterns. In NQL, you can use regex to match patterns with precise rules.

**Note**: Avoid beginning patterns with `*` or `?` as this can lead to performance issues due to increased iterations.

#### Regex: Examples <a href="#regex-examples" id="regex-examples"></a>

{% tabs %}
{% tab title="NQL" %}

```sql
query.domain =~ net_
query.domain =~ netog.i?
query.domain =~ net~
query.domain =~ /[a-z]_/
query.domain =~ /[a-z]\_/ && query.name == neto
```

{% endtab %}
{% endtabs %}

#### Regex: Operator Syntax and Meaning <a href="#regex-operator-syntax-and-meaning" id="regex-operator-syntax-and-meaning"></a>

| Operator | Syntax   | Meaning                                     | Example Field                |
| -------- | -------- | ------------------------------------------- | ---------------------------- |
| `=~`     | `/.*at/` | Matches zero or more characters.            | `query.name =~ /net.*\.com/` |
| `!~`     | `/.*at/` | Negative match for zero or more characters. | `query.name !~ /net.*\.com/` |

#### Regex: Text Boundary Anchors <a href="#regex-text-boundary-anchors" id="regex-text-boundary-anchors"></a>

Boundary anchors specify positions in the text. The start and end characters are implicitly applied to each search and cannot be modified:

| Regexp | Meaning                   | Description                   | Example                 |
| ------ | ------------------------- | ----------------------------- | ----------------------- |
| `^`    | Start of a line or string | Matches the start of a string | `^cat` matches `catdog` |
| `$`    | End of a line or string   | Matches the end of a string   | `cat$` matches `dogcat` |

#### Regex: Choice and Grouping <a href="#regex-choice-and-grouping" id="regex-choice-and-grouping"></a>

Choice and grouping operators allow you to match one or more alternatives or group expressions:

| Regexp      | Meaning         | Description               | Example                                               |
| ----------- | --------------- | ------------------------- | ----------------------------------------------------- |
| `xy`        | x followed by y | Matches "xy"              | `abc\` matches "abc".                                 |
| `x OR y`    | x or y          | Matches "x" or "y"        | ye\` matches "axe" or "aye"                           |
| `abc(def)?` | Grouping        | Matches "abc" or "abcdef" | `abc(def)?` matches `abc` and `abcdef` but not `abcd` |

#### Regex: Repetition (Greedy and Non-Greedy) <a href="#regex-repetition-greedy-and-non-greedy" id="regex-repetition-greedy-and-non-greedy"></a>

Repetition operators match a specified number of occurrences:

| Regexp   | Meaning                          | Description                                                                    |
| -------- | -------------------------------- | ------------------------------------------------------------------------------ |
| `x*`     | Zero or more occurrences of x    | Matches zero or more of "x". Example: `a*` matches "", "a", "aa".              |
| `x+`     | One or more occurrences of x     | Matches one or more of "x". Example: `a+` matches "a", "aa".                   |
| `x?`     | Zero or one occurrence of x      | Matches zero or one of "x". Example: `a?` matches "" or "a".                   |
| `x{n,m}` | Between n and m occurrences of x | Matches between n and m of "x". Example: `a{2,4}` matches "aa", "aaa", "aaaa". |
| `x{n,}`  | n or more occurrences of x       | Matches n or more of "x". Example: `a{2,}` matches "aa", "aaa".                |
| `x{n}`   | Exactly n occurrences of x       | Matches exactly n of "x". Example: `a{3}` matches "aaa".                       |

#### Regex: Character Classes <a href="#regex-character-classes" id="regex-character-classes"></a>

Character classes match specific sets or ranges of characters:

| Regexp     | Meaning                                     | Description                                                              |
| ---------- | ------------------------------------------- | ------------------------------------------------------------------------ |
| `<1-10>`   | Any number between 1 and 10                 | Matches any numeric value between the 2 numbers                          |
| `<01-010>` | Any number between 1 and 10 with leading 0s | Matches any numeric value between the 2 numbers, including leading zeros |

#### Regex: Numeric Ranges <a href="#regex-numeric-ranges" id="regex-numeric-ranges"></a>

Numeric ranges match numbers within a specific range, providing greater flexibility for queries involving numeric values.

| Regexp     | Meaning                                     | Description                                                              |
| ---------- | ------------------------------------------- | ------------------------------------------------------------------------ |
| `<1-10>`   | Any number between 1 and 10                 | Matches any numeric value between the 2 numbers                          |
| `<01-010>` | Any number between 1 and 10 with leading 0s | Matches any numeric value between the 2 numbers, including leading zeros |

**Numeric range examples**

`query.name =~ /ip-(<0-255>-?){3}(<100-200>)\..*/`\
Matches ip-<0-255>.<100-200>.x.x.

`query.name =~ foo<1-100>`\
Matches "foo1", "foo2", ..., "foo100".

**Numeric range performance**

Using numeric range matching can simplify queries for numerical intervals but may increase execution time if used with large ranges or complex regex patterns. As with other regex patterns, avoid starting expressions with `*` or `?` when combining them with numeric ranges to prevent performance degradation.

#### Regex: Special Characters <a href="#regex-special-characters" id="regex-special-characters"></a>

Special characters perform specific functions within regex patterns:

| Regexp | Meaning          | Description                                                                                   |
| ------ | ---------------- | --------------------------------------------------------------------------------------------- |
| `\`    | Escape character | Escapes special characters to be treated as literals. Example: `\.` matches a literal period. |

#### Regex: Case-Insensitive Matching <a href="#regex-case-insensitive-matching" id="regex-case-insensitive-matching"></a>

Perform case-insensitive regular expression matches by appending the `i` flag **after** the closing slash of the pattern.

**Syntax:**

* `/pattern/i` — Matches the pattern without regard to case.

**Examples:**

{% tabs %}
{% tab title="NQL" %}

```sql
query.domain =~ /netography/i        // Matches "Netography", "NETOGRAPHY", "netography", etc.
```

{% endtab %}
{% endtabs %}

**Regex: Reserved Characters**

The following characters are reserved as operators and need to be escaped: `. ? + * | { } [ ] ( ) " \`

### Fuzzy Matching <a href="#fuzzy-matching" id="fuzzy-matching"></a>

Fuzzy matching accounts for variations in spelling by calculating the Levenshtein distance between terms.

{% hint style="info" %}
**🤔What is the Levenshtein Distance?**

The Levenshtein distance is a metric for measuring the difference between two strings. It calculates the minimum number of single-character edits (insertions, deletions, or substitutions) required to change one string into another. For example, the Levenshtein distance between "kitten" and "sitting" is 3, because it requires three edits: replacing 'k' with 's', replacing 'e' with 'i', and adding 'g'. This metric is useful for fuzzy matching, where you want to find matches that are close, but not exact.
{% endhint %}

#### Fuzzy Matching: Operator Syntax and Meaning <a href="#fuzzy-matching-operator-syntax-and-meaning" id="fuzzy-matching-operator-syntax-and-meaning"></a>

| Operator | Syntax  | Meaning                                                  | Example Field         |
| -------- | ------- | -------------------------------------------------------- | --------------------- |
| `=~`     | `cat~`  | Matches terms with an automatically calculated distance. | `query.name =~ cat~`  |
| `!~`     | `cat~`  | Negative fuzzy match with automatic distance.            | `query.name !~ cat~`  |
| `=~`     | `cat~2` | Matches terms with a maximum distance of 2 changes.      | `query.name =~ cat~2` |
| `!~`     | `cat~2` | Negative match with a maximum distance of 2 changes.     | `query.name !~ cat~2` |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fusion.vectra.ai/netography-query-language/nql-overview-and-basics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
