Executes a subquery that generates an in-memory, ad-hoc table
based on its results. The ad-hoc table can be joined with the
results of the primary query using the
match()
function.
Note
There is a limit of 10 ad-hoc tables per query.
For more information on using Ad-hoc tables, see Using Ad-hoc Tables.
defineTable()
is the recommended
alternative to the join()
function,
allowing for easier query writing of complex joins. For more
explanations on the benefits of using ad-hoc tables with
defineTable()
instead of
join()
, see
Ad-hoc Tables vs. join().
Combined with match()
and
readFile()
query functions,
defineTable()
can be used to create several
types of join-like queries — see
defineTable()
Examples.
Parameter | Type | Required | Default Value | Description |
---|---|---|---|---|
end | string | optional[a] | same as primary query | End of time interval of subquery: milliseconds since UNIX epoch or a timestamp relative to the primary query's end time using Relative Time Syntax. For example: if start=7d and the main query's end time is 2024-03-25 14:00:00 , then the defineTable() subquery should would use the time 2024-03-18 14:00:00 . |
include | array of strings | required | Fields to include as columns in the temporary table. If set to * all fields will be included. | |
name | string | required | Name of the ad-hoc table that is generated. Used to reference the table in other functions within the primary query. | |
query [b] | function | required | Subquery used to generate the ad-hoc table. | |
start | string | optional[a] | same as primary query | Start of time interval of subquery: milliseconds since UNIX epoch or a timestamp relative to the primary query's end time using Relative Time Syntax. For example: if start=7d and the main query's end time is 2024-03-25 14:00:00 , then the defineTable() subquery would use the time 2024-03-18 14:00:00 |
view | string | optional[a] | same as primary query | View in which to perform the subquery. |
[a] Optional parameters use their default value unless explicitly set. |
Hide omitted argument names for this function
Omitted Argument NamesThe argument name for
query
can be omitted; the following forms of this function are equivalent:logscale SyntaxdefineTable("value",name="value",include=["value"])
and:
logscale SyntaxdefineTable(query="value",name="value",include=["value"])
These examples show basic structure only.
defineTable()
Operation
The defineTable()
function has specific
implementation and operational considerations, outlined below.
defineTable()
cannot be used with thejoin()
,selfJoin()
orselfJoinFilter()
functions.To ensure optimal performance when using
defineTable()
, follow the best practice described at Ad-hoc Tables Optimization.For more information on the different methods of creating join queries — including ad-hoc tables with the
defineTable()
function — see Join Methods.Important
When using
defineTable()
, be aware that ad-hoc tables are not supported in Alerts, for the reasons explained at Ad-hoc Tables in Live Queries. Use Scheduled Searches instead.Time specification for the
start
andend
must be related to the start and end time of the main query using the Relative Time Syntax. If the parameters are not used, the query will default to using the start and end times of the main query.For example, given a main query with an end time of 2025-07-15 12:00:00 (Noon on 15th July 2025) to 2025-07-15 15:00:00 (3pm on 15th July 2025):
7 days earlier start time
start=7d
would set Noon on 8th July 20251 day earlier start time
start=1d
would set Noon on 14th July 20251 day earlier start time
start=24h
would set Noon on 14th July 20256 hours earlier start time
start=6h
would set 6am on 14th July 2025
Using an absolute time will not set the right value for comparison for the table data.
defineTable()
Syntax Examples
The function's signature combined with
match()
:
defineTable(query={a=hello}, name="tablename", include=[col1,col2,col3])
| match(table="tablename",field=fieldname, column=col1)
For example, to match email data within the same view:
email=bob@example.com firstname=bob lastname=thomas |
loginemail=bob@example.com action=register |
Perform a subquery and a primary query:
defineTable(query={email=*}, name="emails", include=[email,firstname, lastname])
| match(table="emails", field=loginemail, column=email)
The first query in the pipeline is the subquery used for table
definition. The second query in the pipeline is the primary
query that uses match()
.
The following example query combines information about the
ProcessRollUp2
and
NetworkListenIP4
to find
processes that have created listeners on a port.
This is the full query:
logscaledefineTable(query={#event_simpleName=NetworkListenIP4 LocalPort<1024 LocalPort!=0}, name="network_listener", include=[ContextProcessId,LocalAddressIP4, LocalPort]) | #event_simpleName=ProcessRollup2 | match(table="network_listener",field=TargetProcessId,column=ContextProcessId)
The subquery with
defineTable()
generates a result table namednetwork_listener
:ContextProcessId LocalAddressIP4 LocalPort 123 172.16.254.1 1010 456 172.19.254.1 2020 789 190.16.254.1 3030 The second item in the pipeline filters #event_simpleName field to only take the
ProcessRollUp2
value.match()
joins the results of thenetwork_listener
ad-hoc table with the primary query, by matching:TargetProcessId field from the primary query
ContextProcessId column field from the ad-hoc, generated table.
defineTable()
Examples
Click
next to an example below to get the full details.Filter For Items Not Part of Data Set Using defineTable()
Find the set difference using the
defineTable()
function with
!match()
Query
defineTable(
name=session_ids,
query={#repo=B session_id=*},
include=session_id
)
#repo=A session_id=*
| !match(table=session_ids, field=session_id)
Introduction
In this example, the defineTable()
function is used
with a !match()
to search and find all session IDs
from data set A that are not found in data set B.
![]() |
Example incoming data from repository A might look like this:
timestamp | session_id | user_name | action | status |
---|---|---|---|---|
2025-04-01T07:00:00Z | 123456 | john.doe | login | success |
2025-04-01T07:05:00Z | 123457 | jane.smith | download | success |
2025-04-01T07:10:00Z | 123458 | mike.jones | upload | failed |
2025-04-01T07:15:00Z | 123459 | sara.wilson | login | success |
2025-04-01T07:20:00Z | 123460 | bob.brown | logout | success |
Example incoming data from repository B might look like this:
timestamp | session_id | user_name | action | status |
---|---|---|---|---|
2025-04-01T07:00:00Z | 123456 | john.doe | login | success |
2025-04-01T07:05:00Z | 123457 | jane.smith | download | success |
2025-04-01T07:20:00Z | 123460 | bob.brown | logout | success |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable( name=session_ids, query={#repo=B session_id=*}, include=session_id )
Generates an ad-hoc table from repository
B
namedsession_ids
and filters on all events in repositoryB
that contain the field session_id. - logscale
#repo=A session_id=*
Filters for all events from repository
A
, that contain a session_id field. - logscale
| !match(table=session_ids, field=session_id)
Performs a negated match with repository
B
, and returns sessions that exist in repositoryA
but not in repositoryB
. The negation operator is used to return non-matching results. Event Result set.
Summary and Results
The query is used to find the set difference between two repositories. This is, for example, useful for identifying sync issues or performing data consistency checks. Or just to make a cross-repository comparison.
For more information, see also Query Joins and Lookups
Sample output from the incoming example data:
timestamp | session_id | user_name | action | status |
---|---|---|---|---|
2025-04-01T07:10:00Z | 123458 | mike.jones | upload | failed |
2025-04-01T07:15:00Z | 123459 | sara.wilson | login | success |
Perform a Left Join Query to Combine Two Datasets
Query
defineTable(name="users_table",query={orgId=1},include=[username, name])
| operation=createdFile
| match(table=users_table, field=username, strict=false)
| select([username, name])
Introduction
In this example, the defineTable()
function is used
as a left join query to extract and combine information from two
different datasets.
The event set for the query is in one repository, but the event set for each query is shown separately to identify the two sets of information. The first event set is:
username | name | orgId |
---|---|---|
user1 | John Doe | 1 |
user2 | Jane Doe | 1 |
user3 | Bob Smith | 2 |
and the other event set:
username | operation |
---|---|
user1 | createdFile |
user2 | deletedFile |
user3 | createdFile |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable(name="users_table",query={orgId=1},include=[username, name])
Generates an ad-hoc table named
users_table
that has the fields username and name and includes users where orgId field equals1
. - logscale
| operation=createdFile
Filters on the field operation for users who performed the action of creating a file by looking for the value
createdFile
. - logscale
| match(table=users_table, field=username, strict=false)
Joins with
users_table
table. - logscale
| select([username, name])
Selects the username and name fields to be displayed from the event set.
Event Result set.
Summary and Results
The result will output two events:
username | name |
---|---|
user1 | John Doe |
user3 | no value |
where user3 has no value since
this user is not included in the
users_table
table
user2
(not belonging to
orgId=1).
Perform a Nested Join Query to Combine Two Datasets and Two Tables
Query
defineTable(name="organization_table",query={orgId=1},include=[username, orgId],view=organizations)
| defineTable(name="users_table",query={match(table=organization_table, field=username)},include=[username, name])
| operation=createdFile
| match(table=users_table, field=username)
| select([username, name])
Introduction
Similar to the inner join
example, defineTable()
first creates a separate
table for organizations belonging to a different view, which is then
matched against a users' table as a nested-like join.
The event set for the query is in one repository, but the event set for each query is shown separately to identify the two sets of information. The first event set is:
username | orgId |
---|---|
user1 | 1 |
user2 | 1 |
user3 | 2 |
and the other event set:
username | name |
---|---|
user1 | John Doe |
user2 | Jane Doe |
user3 | Bob Smith |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable(name="organization_table",query={orgId=1},include=[username, orgId],view=organizations)
Generates an ad-hoc table named
organization_table
that has the fields username and orgId and includes users where orgId field equals1
from theorganizations
view. - logscale
| defineTable(name="users_table",query={match(table=organization_table, field=username)},include=[username, name])
Generates an ad-hoc table named
users_table
that has the fields username and name and enriches rows with orgId=1 fromorganization_table
- logscale
| operation=createdFile
Filters on the field operation for users who performed the action of creating a file by looking for the value
createdFile
. - logscale
| match(table=users_table, field=username)
Joins with
users_table
table, to filter out users who are not from orgId=1 and to enrich with the users' names. - logscale
| select([username, name])
Selects the username and name fields to be displayed from the event set.
Event Result set.
Summary and Results
The result will output one event:
username | name |
---|---|
user1 | John Doe |
Perform a Right Join Query to Combine Two Datasets
Query
defineTable(name="users",query={orgId=1},include=[username, name])
| defineTable(name="operations",query={*},include=[username, operation])
| readFile(users)
| match(operations, field=username, strict=false)
| select([username, operation])
Introduction
In this example, the defineTable()
function is used
as a right join query to extract and combine information from two
different datasets.
The event set for the query is in one repository, but the event set for each query is shown separately to identify the two sets of information. The first event set is:
username | name | orgId |
---|---|---|
user1 | John Doe | 1 |
user2 | Jane Doe | 1 |
user3 | Bob Smith | 2 |
and the other event set:
username | operation |
---|---|
user1 | createdFile |
user3 | createdFile |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable(name="users",query={orgId=1},include=[username, name])
Generates an ad-hoc table named
users
that has the fields username and name and includes users where orgId field equals1
. - logscale
| defineTable(name="operations",query={*},include=[username, operation])
Defines a new ad-hoc table that uses all the fields (username and operation) in a table named
operations
. - logscale
| readFile(users)
Reads the
users
ad-hoc table as events usingreadFile()
. - logscale
| match(operations, field=username, strict=false)
Matches the events that have a matching operation from the
operations
table with theusers
table using the username as the common field. Events are not filtered if the events do not match, (implying a right join), by usingstrict=false
- logscale
| select([username, operation])
Selects the username and operation fields to be displayed from the event set.
Event Result set.
Summary and Results
The result will output two events:
username | operation |
---|---|
user1 | createdFile |
user2 | no value |
Note that in the event set all operations have been included even when
there is no match between the
username field, resulting in the
no value
for
user2
. If
strict=true
had been used to
the match()
function, then the event for
user2
would not have been outputted.
Perform an Inner Join Query to Combine Two Datasets
Query
defineTable(name="users_table",query={orgId=1},include=[username, name])
| orgId=1
| operation=createdFile
| match(table=users_table, field=username)
| select([username, name])
Introduction
In this example, the defineTable()
function is used
as an inner join query to extract and combine information from two
different datasets.
The event set for the query is in one repository, but the event set for each query is shown separately to identify the two sets of information. The first event set is:
username | name | orgId |
---|---|---|
user1 | John Doe | 1 |
user2,Jane Doe",1 | ||
user3 | Bob Smith | 2 |
and the other event set:
username | operation |
---|---|
user1 | createdFile |
user2 | deletedFile |
user3 | createdFile |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable(name="users_table",query={orgId=1},include=[username, name])
Generates an ad-hoc table named
users_table
that has the fields username and name and filters used where the orgId field equals1
. - logscale
| orgId=1
Selects only users from the orgId where the value equals
1
. - logscale
| operation=createdFile
Filters on the field operation for users who performed the action of creating a file by looking for the value
createdFile
. - logscale
| match(table=users_table, field=username)
Joins the filtered events (users that created a file in organization 1) using the username field with the
users_table
table. - logscale
| select([username, name])
Selects the username and name fields to be displayed in the result set.
Event Result set.
Summary and Results
The result will output one event:
username | name |
---|---|
user1 | John Doe |
Set Time Interval From Within Query with defineTable()
Set the time interval and related metadata from within the query
instead of through the test QueryJobs API or UI using the
defineTable()
function
Query
setTimeInterval(start="1h", end="30min")
| defineTable(
start=7d,
end=1d,
query={...},
name="ended_queries")
| match(table="ended_queries", field=queryID, strict=true)
Introduction
In this example, the setTimeInterval()
function is
used with the defineTable()
function to define a
new time interval for the subqueries, before running this.
Note that the setTimeInterval()
function must
appear before any defineTable()
definitions and
only one time in a query.
For more information about time specification options, see Search API Time Specification.
Step-by-Step
Starting with the source repository events.
- logscale
setTimeInterval(start="1h", end="30min")
Recalls the
defineTable()
subquery time interval. This means that the subquery will start at7d+30min
, and will end at1d+30min
. - logscale
| defineTable( start=7d, end=1d, query={...}, name="ended_queries")
Generates an ad-hoc table named
ended_queries
and computes the relative time points to the primary query's time end time. This means that the subquery will start at7d+30min
, and will end at1d+30min
- logscale
| match(table="ended_queries", field=queryID, strict=true)
Joins the filtered events where the value equals
queryID
with the ended_queries table. Event Result set.
Summary and Results
This query demonstrates how to use
setTimeInterval()
to define the timespan for a
defined table query.
Using Ad-hoc Table With CSV File
Query
defineTable(name="users_table",query={match(file=organizations.csv, field=username)
| orgId=1 },include=[username, name])
| operation=createdFile
| match(table=users_table, field=username)
| select([username, name])
Introduction
In this example, the defineTable()
is used to
extract and combine information from two different datasets, with the
mapping between username and
orgId stored in a CSV file. The
example file organizations.csv
has the following content:
username,orgId
user1,1
user2,1
user3,2
The event set for the query is in one repository, but the event set for each query is shown separately to identify the two sets of information. The first event set is:
username | name |
---|---|
user1 | John Doe |
user2 | Jane Doe |
user3 | Bob Smith |
and the other event set:
username | operation |
---|---|
user1 | createdFile |
user2 | deletedFile |
user3 | createdFile |
Step-by-Step
Starting with the source repository events.
- logscale
defineTable(name="users_table",query={match(file=organizations.csv, field=username) | orgId=1 },include=[username, name])
Generates an ad-hoc table named
users_table
that has the fields username and name and includes users where orgId field equals1
. Then usesmatch()
to enrich rows with orgId fromorganizations.csv
file. - logscale
| operation=createdFile
Filters on the field operation for users who performed the action of creating a file by looking for the value
createdFile
. - logscale
| match(table=users_table, field=username)
Joins the username field with the
users_table
table, to filter out users who are not from orgId=1 and to enrich with the users' names. - logscale
| select([username, name])
Selects the username and name fields to be displayed from the event set.
Event Result set.
Summary and Results
The result will output one event:
username | name |
---|---|
user1 | John Doe |