
Use a subsearch
In this section you will learn how to correlate events by using subsearches.
A subsearch is a search that is used to narrow down the set of events that you search on. The result of the subsearch is then used as an argument to the primary, or outer, search. Subsearches are enclosed in square brackets within a main search and are evaluated first.
Let's find the single most frequent shopper on the Buttercup Games online store, and what that shopper has purchased.
The following examples show why a subsearch is useful. Example 1 shows how to find the most frequent shopper without a subsearch. Example 2 shows how to find the most frequent shopper with a subsearch.
Example 1: Search without a subsearch
You want to find the single most frequent shopper on the Buttercup Games online store and what that shopper has purchased. Use the top
command to return the most frequent shopper.
- Start a new search.
- Change the time range to All time.
- To find the shopper who accessed the online shop the most, use this search.
sourcetype=access_* status=200 action=purchase | top limit=1 clientip
- The
limit=1
argument specifies to return 1 value. Theclientip
argument specifies the field to return.
- This search returns one
clientip
value, 87.194.216.51, which you will use to identify the VIP shopper.
- You now need to run another search to determine how many different products the VIP shopper has purchased.
- Use the
stats
command to count the purchases by this VIP customer.sourcetype=access_* status=200 action=purchase clientip=87.194.216.51 | stats count, dc(productId), values(productId) by clientip
- This search uses the
count()
function to return the total count of the purchases for the shopper. Thedc()
function is the distinct_count function. Use this function to count the number of different, or unique, products that the shopper bought. Thevalues
argument is used to display the actual product IDs in the results.
The drawback to this approach is that you have to run two searches each time you want to build this table. The top purchaser is not likely to be the same person at any given time range.
Example 2: Search with a subsearch
Let's start with our first requirement, to identify the single most frequent shopper on the Buttercup Games online store.
- Copy and paste the following search into the Search bar and run the search.
sourcetype=access_* status=200 action=purchase | top limit=1 clientip | table clientip
- This search returns the clientip for the most frequent shopper,
clientip=87.194.216.51
. This search is almost identical to the search in Example 1 Step 1. The difference is the last piped command,| table clientip
, which displays the clientip information in a table.
- To find what this shopper has purchased, you run a search using the same data. You provide the result of the search for the most frequents shopper as one of the criteria for the purchases search.
- The search to identify the most frequent shopper becomes the subsearch for the search to determine what the shopper has purchased. Because you are searching the same data, the beginning of the main search is identical to the beginning of the subsearch.
- A subsearch is enclosed in square brackets [ ] and processed first when the search is parsed.
- Copy and paste the following search into the Search bar and run the search.
sourcetype=access_* status=200 action=purchase [search sourcetype=access_* status=200 action=purchase | top limit=1 clientip | table clientip] | stats count, dc(productId), values(productId) by clientip
- Because the
top
command returns the count and percent fields, thetable
command is used to keep only theclientip
value.
- These results should match the result of the two searches in Example 1, if you run it on the same time range. If you change the time range, you might see different results because the top purchasing customer will be different.
- Note: The performance of this subsearch depends on how many distinct IP addresses match
status=200 action=purchase
. If there are thousands of distinct IP addresses, thetop
command has to keep track of all of those addresses before the top 1 is returned, impacting performance. By default, subsearches return a maximum of 10,000 results and have a maximum runtime of 60 seconds. In large production environments, it is possible that the subsearch in this example will timeout before it completes. The best option is to rewrite the query to limit the number of events that the subsearch must process. Alternatively, you can increase the maximum results and maximum runtime parameters.
Column Rename count Total Purchased dc(productId) Total Products values(productId) Products ID clientip VIP Customer - To rename the fields, copy and paste the following search into the Search bar and run the search.
sourcetype=access_* status=200 action=purchase [search sourcetype=access_* status=200 action=purchase | top limit=1 clientip | table clientip] | stats count AS "Total Purchased", dc(productId) AS "Total Products", values(productId) AS "Products ID" by clientip | rename clientip AS "VIP Customer"
- Experiment with this search.
- What happens when you run the search over different time periods? What if you wanted to find the top product sold and how many people bought it?
Next step
This completes Part 4 of the Search Tutorial.
You have learned how to use fields, the Splunk search language, and subsearches to search your data. Continue to Part 5: Enriching events with lookups.
See also
About subsearches in the Search Manual
The top command in the Search Reference
The stats command in the Search Reference
PREVIOUS Use the search language |
NEXT Enabling field lookups |
This documentation applies to the following versions of Splunk® Enterprise: 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.6, 6.5.7, 6.5.8, 6.5.9, 6.5.10, 6.6.0, 6.6.1, 6.6.2, 6.6.3, 6.6.4, 6.6.5, 6.6.6, 6.6.7, 6.6.8, 6.6.9, 6.6.10, 6.6.11, 6.6.12
Feedback submitted, thanks!