You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/user/Searching_Filtering_and_More.md
+50-5Lines changed: 50 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,6 +41,14 @@ counterparts.
41
41
-`dedup`: Remove duplicate entries from the result set.
42
42
-`sort`: Sort the result set based on specified criteria.
43
43
44
+
`select` and `filter` can walk nested fields with double-underscore paths
45
+
(eg. `extracted_fields__auth__display_name`), which is useful when different
46
+
sourcetypes populate `extracted_fields` with different shapes. A path segment
47
+
that's missing on a given event resolves to `None` rather than raising an
48
+
error, and a `filter` predicate (`icontains`, `startswith`, etc.) that can't
49
+
be evaluated against `None` is treated as not matching, instead of aborting
50
+
the whole search - the same way a database `NULL` behaves for most lookups.
51
+
44
52
## Visualization Commands
45
53
Visualization commands take a result set and generate a table, chart, or other visualization. These commands help you to display your data in a meaningful and interactive way.
46
54
@@ -61,25 +69,28 @@ Here are some example commands to use the `qs_group_by` functionality:
61
69
62
70
```bash
63
71
# Group records by a single field and calculate the average of another field
# Filiter records, select nested fields and calculate the difference in days between the created field (index timestamp) and the timestamp field (timestamp from the text of the event)
73
81
search
74
82
| qs_values created event_host=KT(extracted_fields__host) timestamp=KT(extracted_fields__timestamp) message=KT(extracted_fields__msg)
> **Note:** these expressions have no spaces inside the parentheses on purpose - see
87
+
> [Quoting Multi-Word Arguments](#quoting-multi-word-arguments) below for why.
88
+
78
89
### Explanation
79
90
80
-
-`qs_group_by extracted_fields__foo avg_bar=Avg(Cast(extracted_fields__bar,IntegerField))`: Groups records by the `extracted_fields__foo` field and calculates the average of the `extracted_fields__bar` field, casting it to an integer.
91
+
-`qs_group_by extracted_fields__foo avg_bar=Avg(Cast(extracted_fields__bar,IntegerField))`: Groups records by the `extracted_fields__foo` field and calculates the average of the `extracted_fields__bar` field, casting it to an integer.
81
92
-`qs_group_by extracted_fields__foo extracted_fields__bar count=Count('id')`: Groups records by the `extracted_fields__foo` and `extracted_fields__bar` fields and counts the number of records in each group.
82
-
-`qs_group_by extracted_fields__foo avg_bar=Avg(Cast(extracted_fields__bar,IntegerField)) | qs_having avg_bar__gt=1`: Groups records by the `extracted_fields__foo` field, calculates the average of the `extracted_fields__bar` field, and filters the groups to include only those with an average greater than 1.
93
+
-`qs_group_by extracted_fields__foo avg_bar=Avg(Cast(extracted_fields__bar,IntegerField)) | qs_having avg_bar__gt=1`: Groups records by the `extracted_fields__foo` field, calculates the average of the `extracted_fields__bar` field, and filters the groups to include only those with an average greater than 1.
83
94
84
95
The `qs_group_by` command is a powerful tool for aggregating and analyzing data within Delve, allowing you to perform complex queries and calculations on grouped records.
85
96
@@ -236,6 +247,26 @@ The `qs_*` commands are designed to modify a Django QuerySet using methods on th
236
247
237
248
When you use `qs_*` commands, the arguments are parsed into expressions that Django can understand. This means you can use functions and complex expressions to manipulate your data.
238
249
250
+
Each argument token is run through Python's `ast.parse` so that functioncalls
251
+
(`Cast(...)`, `Trunc(...)`, `F(...)`, etc.) and arithmetic can be used directly.
252
+
This has two consequences worth knowing before you write one of these commands:
253
+
254
+
#### Quoting Multi-Word Arguments
255
+
256
+
A query line is first split into pipeline stages on `|`, then each stage is
257
+
tokenized on whitespace (via `shlex.split`) before argument parsing even
258
+
starts. That means:
259
+
260
+
- **An expression containing `, ` (a comma followed by a space) gets split
261
+
into two tokens and fails with a `SyntaxError`.** Either drop the space
262
+
(`Cast(field,IntegerField)`) or wrap the whole expression in quotes:
- **A value that should be treated as a literal string but starts with `-`
265
+
(eg. a descending sort field) looks like a CLI flag and needs to be a quoted
266
+
Python string literal:**`qs_order_by "'-count'"`, not `qs_order_by -count`
267
+
(the latter gets parsed as unary negation of the name `count` and raises a
268
+
`TypeError`).
269
+
239
270
### Available Field Classes
240
271
241
272
The following Django model field classes are available forusein query annotations and transformations (Can be passed to Cast, ExpressionWrapper, etc.):
@@ -524,7 +555,7 @@ Here are some example usages of the `qs_*` commands, starting with the `search`
524
555
525
556
```bash
526
557
# Search for events and annotate them with additional fields
0 commit comments