1. Go to this page and download the library: Download level23/druid-client library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
level23 / druid-client example snippets
// Register the druid-client service provider
$app->register(Level23\Druid\DruidServiceProvider::class);
error_reporting(E_ALL);
ini_set('display_errors', 'On');
include __DIR__ . '/../vendor/autoload.php';
use Level23\Druid\DruidClient;
use Level23\Druid\Types\Granularity;
use Level23\Druid\Filters\FilterBuilder;
$client = new DruidClient(['router_url' => 'https://router.url:8080']);
$response = $client->query('traffic-hits', Granularity::ALL)
// REQUIRED: you have to select the interval where to select the data from.
->interval('now - 1 day', 'now')
// Simple dimension select
->select('browser')
// Select a dimension with a different output name.
->select('country_iso', 'Country')
// Alternative way to select a dimension with a different output name.
// If you want, you can select multiple dimensions at once.
->select(['mccmnc' => 'carrierCode'])
// Select a dimension, but change its value using a lookup function.
->lookup('carrier_title', 'mccmnc', 'carrierName', 'Unknown')
// Select a dimension, but use an expression to change the value.
->selectVirtual("timestamp_format(__time, 'yyyy-MM-dd HH:00:00')", 'hour')
// Summing a metric.
->sum('hits', 'totalHits')
// Sum hits which only occurred at night
->sum('hits', 'totalHitsNight', function(FilterBuilder $filter) {
$filter->whereInterval('__time', ['yesterday 20:00/today 6:00']);
})
// Count the total number of rows (per the dimensions selected) and store it in totalNrRecords.
->count('totalNrRecords')
// Count the number of dimensions. NOTE: Theta Sketch extension is
// Create a custom guzzle client which uses a http proxy.
$guzzleClient = new GuzzleHttp\Client([
'proxy' => 'tcp://localhost:8125',
'timeout' => 30,
'connect_timeout' => 10
]);
// Create a new DruidClient, which uses our custom Guzzle Client
$druidClient = new DruidClient(
['router_url' => 'https://druid.router.com'],
$guzzleClient
);
// Query stuff here....
$client = new DruidClient(['router_url' => 'https://router.url:8080']);
// retrieve our query builder, group the results per day.
$builder = $client->query('wikipedia', Granularity::DAY);
// Now build your query ....
// $builder->select( ... )->where( ... )->interval( ... );
$client = new DruidClient(['router_url' => 'https://router.url:8080']);
// Store a lookup, which is populated by fetching data from a database
$client->lookup()->jdbc(
connectUri: 'jdbc:mysql://localhost:3306/my_database',
username: 'username',
password: 'p4ssw0rd!',
table: 'users',
keyColumn: 'id',
valueColumn: 'name',
filter: "state='active'",
tsColumn: 'updated_at',
)
->pollPeriod('PT30M') // renew our data every 30 minutes
->store(
lookupName: 'usernames',
tier: 'company'
);
$client = new DruidClient(['router_url' => 'https://router.url:8080']);
// For example, this returns my-query6148716d3772c
$queryId = uniqid('my-query');
// Please note: this will be blocking until we have got result from druid.
// So cancellation has to be done within another php process.
$result = $client
->query('wikipedia', Granularity::DAY)
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select(['namespace', 'page'])
->execute(['queryId' => $queryId]);
$client->cancelQuery('my-query6148716d3772c')
// Select an interval with string values. Anything which can be parsed by the DateTime object
// can be given. Also, "yesterday" or "now" is valid.
$builder->interval('2019-12-23', '2019-12-24');
// When a string is given which contains a slash, we will split it for you and parse it as "begin/end".
$builder->interval('yesterday/now');
// A "raw" interval as druid uses them is also allowed
$builder->interval('2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z');
// You can also give DateTime objects
$builder->interval(new DateTime('yesterday'), new DateTime('now'));
// Carbon is also supported, as it extends DateTime
$builder->interval(Carbon::now()->subDay(), Carbon::now());
// Timestamps are also supported:
$builder->interval(1570643085, 1570729485);
// Build a select query
$builder = $client->query('wikipedia')
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select(['__time', 'channel', 'user', 'deleted', 'added'])
->limit(10);
// Execute the query for "page 1"
$response1 = $builder->selectQuery();
// Now, request "page 2".
$builder->pagingIdentifier($response1->getPagingIdentifier());
// Execute the query for "page 2".
$response2 = $builder->selectQuery($context);
// Build a groupBy query with subtotals
$response = $client->query('wikipedia')
->interval('2015-09-12 20:00:00', '2015-09-12 22:00:00')
->selectVirtual("timestamp_format(__time, 'yyyy-MM-dd HH:00:00')", 'hour')
->select('namespace')
->count('edits')
->longSum('added')
// select all namespaces which begin with Draft.
->where('namespace', 'like', 'Draft%')
->subtotals([
['hour', 'namespace'], // get the results per hour, namespace
['hour'], // get the results per hour
[] // get the results in total (everything together)
])
->groupBy();
$builder = $client->query('wikipedia')
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select(['__time', 'channel', 'user', 'deleted', 'added'])
->limit(10);
// Show the query as an array
print_r($builder->toArray());
$builder = $client->query('wikipedia')
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select(['__time', 'channel', 'user', 'deleted', 'added'])
->limit(10);
// Show the query as an array
var_export($builder->toJson());
$builder = $client->query('wikipedia');
$builder = $client->query('hits_short');
// For example, use a different dataSource if the given date is older than one week.
if( Carbon::parse($date)->isBefore(Carbon::now()->subWeek()) ) {
$builder->from('hits_long');
}
$builder = $client->query('hits_us')
->union(['hits_eu', 'hits_as'], true);
// This will result in a query on the dataSources: hits_us, hits_eu and hits_as.
// This is because the "append" argument is set to true.
$builder = $client->query('hits_us')
->union(['hits_eu', 'hits_as'], false);
// This will result in a query on the dataSources: hits_eu and hits_as.
// This is because the "append" argument is set to false. It will overwrite the current dataSource.
// count how many page views are done by kids
$builder->longSum('pageViews', 'pageViewsByKids', function(FilterBuilder $filter) {
$filter->where('age', '<=', 16);
});
$builder->count('nrOfResults');
$builder->sum('views', 'totalViews');
$builder->min('age', 'minAge');
$builder->max('age', 'maxAge');
$builder->first('device');
$builder->last('email');
$builder->any('price');
$builder->javascript(
'result',
['x', 'y'],
"function(current, a, b) { return current + (Math.log(a) * b); }",
"function(partialA, partialB) { return partialA + partialB; }",
"function() { return 10; }"
);
$builder->cardinality(
'itemsPerCountry',
function(DimensionBuilder $dimensions) {
// select the country name by its iso value.
$dimensions->lookup('country_name', 'iso');
},
false, # byRow
false # round
);
// Count the distinct number of categories.
$builder->distinctCount('category_id', 'categoryCount');
// Get the 95th percentile of the salaries per country.
$builder = $client->query('dataSource')
->interval('now - 1 hour', 'now')
->select('country')
->doublesSketch('salary', 'salaryData') // this collects the data
->quantile('quantile95', 'salaryData', 0.95) // this uses the data which was collected
// filter on all places where city name is NULL.
$builder->whereNull('city');
// filter on all places where the country is NOT NULL!
$builder->whereNot(function (FilterBuilder $filterBuilder) {
$filterBuilder->whereNull('country');
});
// filter where country in "it", "de" or "au".
$builder->whereIn('country_iso', ['it', 'de', 'au']);
$client = new \Level23\Druid\DruidClient([
'router_url' => 'https://router.url:8080',
]);
$client->query('myDataSource')
->interval('now - 1 day', 'now')
// Select records where the first and third bit are enabled (1 and 4)
->whereFlags('flags', (1 | 4));
// example using a having filter
$builder->having( new GreaterThanHavingFilter('totalViews', 15) );
// example using a "normal" filter.
$builder->having( new SelectorFilter('totalViews', '15') );
// Increase our reward with $2,00 if this sale was done by a promoter.
$builder->virtualColumn('if(promo_id > 0, reward + 2, 0)', 'rewardWithPromoterPayout', 'double')
// Now sum all our rewards with the promoter payouts
// Select the mobile device type as text, but only if isMobileDevice = 1
$builder->selectVirtual(
"if( isMobileDevice = 1, case_simple( mobileDeviceType, '1', 'samsung', '2', 'apple', '3', 'nokia', 'other'), 'no mobile device')",
"deviceType"
);
// Get the 95th percentile of the salaries per country.
$builder = $client->query('dataSource')
->interval('now - 1 hour', 'now')
->select('country')
->doublesSketch('salary', 'salaryData') // this collects the data
->quantile('quantile95', 'salaryData', 0.95) // this uses the data which was collected
// Get the 95th percentile of the salaries per country.
$builder = $client->query('dataSource')
->interval('now - 1 hour', 'now')
->select('country')
->doublesSketch('salary', 'salaryData') // this collects the data
->quantiles('quantile95', 'salaryData', [0.8, 0.95]) // this uses the data which was collected
// Create our builder
$builder = $client->query('dataSource')
->interval('now - 1 hour', 'now')
->select('country')
->doublesSketch('salary', 'salaryData') // this collects the data
// This would spit the data in "buckets".
// It will return an array with the number of people earning, 1000 or less,
// the number of people earning 1001 to 1500, etc.
->histogram('salaryGroups', 'salaryData', [1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500]);
// Create our builder
$builder = $client->query('dataSource')
->interval('now - 1 hour', 'now')
->select('country')
->doublesSketch('salary', 'salaryData') // this collects the data
// This will get the ranking of the value 2500 compared to all available "salary" values in the resultset.
// The result will be a float between 0 and 1.
->rank('mySalaryRank', 'salaryData', 2500);
php
$builder = $client->query('wikipedia', Granularity::ALL)
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select('channel')
->count('edited')
->limit(10)
->orderBy('edited', 'desc');
// Create specific query context for our query
$context = new TopNQueryContext();
$context->setMinTopNThreshold(1000);
// Execute the query
$response = $builder->topN($context);
php
// Build a select query
$builder = $client->query('wikipedia')
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->select(['__time', 'channel', 'user', 'deleted', 'added'])
->orderByDirection(OrderByDirection::DESC)
->limit(10);
// Execute the query.
$response = $builder->selectQuery($context);
// ... Use your response (page 1) here! ...
// echo "Identifier for page 2: " . var_export($response->pagingIdentifier(), true) . "\n\n";
// Now, request "page 2".
$builder->pagingIdentifier($response->pagingIdentifier());
// Execute the query.
$response = $builder->selectQuery($context);
// ... Use your response (page 2) here! ...
php
// Example of setting query context. It can also be supplied as an array in the selectQuery() method call.
$context = new QueryContext();
$context->setPriority(100);
// Execute the query.
$response = $builder->selectQuery($context);
php
// Example of setting query context. It can also be supplied as an array in the scan() method call.
$context = new ScanQueryContext();
$context->setPriority(100);
$context->setMaxRowsQueuedForOrdering(5000);
// Execute the query.
$response = $builder->scan($context);
php
// Example of setting query context. It can also be supplied as an array in the timeseries() method call.
$context = new TimeSeriesQueryContext();
$context->setSkipEmptyBuckets(true);
// Execute the query.
$response = $builder->timeseries($context);
php
// Build a Search Query
$builder = $client->query('wikipedia')
->interval('2015-09-12 00:00:00', '2015-09-13 00:00:00')
->dimensions(['namespace']) // If left out, all dimensions are searched
->searchContains('wikipedia')
->limit(150);
// Execute the query, sorting by String Length (shortest first).
$response = $builder->search([], SortingOrder::STRLEN);
php
// Example of setting query context. It can also be supplied as an array in the search() method call.
$context = new QueryContext();
$context->setPriority(100);
// Execute the query.
$response = $builder->search($context);
php
// retrieve the details regarding the given interval.
$response = $client->metadata()->interval('wikipedia', '2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z');
php
$client = new DruidClient(['router_url' => 'http://127.0.0.1:8888']);
// Build our kill task and execute it.
$taskId = $client->kill('wikipedia')
->interval('2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z ')
->markAsUnused() // mark segments as unused
->execute();
echo "Kill task inserted with id: " . $taskId . "\n";
// Start polling task status.
while (true) {
$status = $client->taskStatus($taskId);
echo $status->getId() . ': ' . $status->getStatus() . "\n";
if ($status->getStatus() != 'RUNNING') {
break;
}
sleep(2);
}
// Or, simply use:
// $status = $client->pollTaskStatus($taskId);
echo "Final status: \n";
print_r($status->data());
php
// First, define your inputSource.
$inputSource = new \Level23\Druid\InputSources\AzureInputSource([
'azure://bucket/file1.json',
'azure://bucket/file2.json',
]);
# Now, start building your task (import it into a datasource called azureData)
$indexTaskBuilder = $client->index('azureData', $inputSource);
// $indexTaskBuilder-> ...
php
// First, define your inputSource.
$inputSource = new \Level23\Druid\InputSources\GoogleCloudInputSource([
'gs://bucket/file1.json',
'gs://bucket/file2.json',
]);
# Now, start building your task (import it into a datasource called googleData)
$indexTaskBuilder = $client->index('googleData', $inputSource);
// $indexTaskBuilder-> ...