/elasticaggregator-php

Easier ElasticSearch aggregation queries in PHP

Primary LanguagePHPApache License 2.0Apache-2.0

ElasticAggregator

An utility PHP wrapper for elasticsearch-php, for an easier usage of ElasticSearch's Aggregation framework. Its DSL is fairly straight-forward, but nested arrays are tedious and error-prone to be manually constructed. Also resulting responses have a quite verbose structure which is not typically necessary.

Features and goals

TODO

  • Decide a better naming convention of public functions (to reflect better the underlying bucketing and metric aggregations), this will break code compatibility with this initial version
  • Support for more than one aggregation at any query level (currenly all bucketing aggregations are nested within the previous aggregation)
  • Improve the overall the flexibility of the library, now this only works on trivial use cases
  • Write tests for all existing aggregation queries
  • Use 4 spaces instead of tabs? That PSR-2 stuff... :(
  • Is it good idea to configure index name at Aggregator constructor but configure object's type in exec() method?
  • Actual documentation on how stuff works, especially if the codebase grows significantly bigger (unit tests document things a bit but not sufficiently)

Example usage

// Assuming this file is under "src/" or something similar...
include(__DIR__ . '/../vendor/autoload.php');

// Create the standard ElasticSearch client object
$client = new \Elasticsearch\Client(array(
    'hosts' => array('localhost:9200'),
));

// Create the aggregator, configure the index name
$aggregator = new \NikoNyrh\ElasticAggregator\Aggregator(
    $client,
    array('index' => 'index_name')
);

// For each "user" get stats on post_length field
$result = $aggregator
    ->aggregate('terms', 'user')
    ->stats('post_length')
    ->exec('type_name');

echo json_encode($result, JSON_PRETTY_PRINT);

Result:

{
    "User 4": {
        "post_length": {
            "count": 25,
            "min": 34,
            "max": 193,
            "avg": 109.44,
            "sum": 2736
        }
    },
    "User 2": {
        "post_length": {
            "count": 22,
            "min": 31,
            "max": 199,
            "avg": 121.5,
            "sum": 2673
        }
    }
}

The corresponding raw query and response of this simple aggregation look like this:

{
    "index": "index_name",
    "type": "type_name",
    "body": {
        "size": 0,
        "aggs": {
            "user_agg": {
                "terms": {
                    "field": "user"
                },
                "aggs": {
                    "post_length_stats": {
                        "stats": {
                            "field": "post_length"
                        }
                    }
                }
            }
        }
    }
}

and

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 100,
        "max_score": 0,
        "hits": []
    },
    "aggregations": {
        "user_agg": {
            "buckets": [
                {
                    "key": "User 4",
                    "doc_count": 25,
                    "post_length_stats": {
                        "count": 25,
                        "min": 34,
                        "max": 193,
                        "avg": 109.44,
                        "sum": 2736
                    }
                },
                {
                    "key": "User 2",
                    "doc_count": 22,
                    "post_length_stats": {
                        "count": 22,
                        "min": 31,
                        "max": 199,
                        "avg": 121.5,
                        "sum": 2673
                    }
                }
            ]
        }
    }
}

I guess you see my point on why this is usually overly verbose.

Installation

Since this project is still at a very early stage, it isn't added to Packagist. For composer to find this project you need to add this repository explicitly:

{
    "require": {
        "nikonyrh/elasticaggregator-php": "0.*"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/nikonyrh/elasticaggregator-php"
        }
    ]
}

License

Copyright 2014 Niko Nyrhilä

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.