pdphilip / laravel-opensearch

An OpenSearch implementation of Laravel's Eloquent ORM
MIT License
16 stars 1 forks source link

[Upgraded] Support for multiple aggregations #3

Closed ftrudeau-pelcro closed 1 month ago

ftrudeau-pelcro commented 2 months ago

Hey there @pdphilip, thanks for this package.

Would it be possible to add support for multiple aggregations.

Using your package, the rawAggregation query below returns only one collection, yet there's actually 3 results: min_runtime, avg_runtime and max_runtime.

$body = [
            'size' => 0,
            'aggs' => [
                'min_runtime' => [
                    'min' => [
                        'field' => 'runtime',
                    ],
                ],
                'avg_runtime' => [
                    'avg' => [
                        'field' => 'runtime',
                    ],
                ],
                'max_runtime' => [
                    'max' => [
                        'field' => 'runtime',
                    ],
                ],
            ],
            'query' => [
                'bool' => [
                    'must' => [
                        'range' => [
                            'datetime' => [
                                'gte' => '2024-07-03',
                                'lte' => '2024-07-09',
                            ]
                        ]
                    ]
                ]
            ]
        ];
        $results = MyLog::rawAggregation($body);
        dump($results);
        exit;

Output of the DSL query from Dev Tools:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 10000,
      "relation": "gte"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "avg_runtime": {
      "value": 1.1940759289359395
    },
    "min_runtime": {
      "value": 0.15059208869934082
    },
    "max_runtime": {
      "value": 66.78320789337158
    }
  }
}
pdphilip commented 2 months ago

Hey @ftrudeau-pelcro, since you're doing basic aggs, why not just use the build-in Eloquent methods? ex:

$results['max'] = MyLog::where('datetime', '>=', '2024-07-03')->where('datetime', '<=', '2024-07-09')->max('runtime');
$results['min'] = MyLog::where('datetime', '>=', '2024-07-03')->where('datetime', '<=', '2024-07-09')->min('runtime');
$results['avg'] = MyLog::where('datetime', '>=', '2024-07-03')->where('datetime', '<=', '2024-07-09')->avg('runtime');

Docs: https://opensearch.pdphilip.com/aggregation#basic-aggregations

Let me know if that worked, or what I missed.

ftrudeau-pelcro commented 2 months ago

Hey @pdphilip.

Yes, that's what I ended up using:

MyLog::whereBetween('datetime', [$period_start->toIso8601String(), $period_end->toIso8601String()])->avg('runtime') MyLog::whereBetween('datetime', [$period_start->toIso8601String(), $period_end->toIso8601String()])->min('runtime') MyLog::whereBetween('datetime', [$period_start->toIso8601String(), $period_end->toIso8601String()])->max('runtime')

Works fine of course! It's just a little sub-optional, since three queries are ran instead of just one which would yield the results of the three aggregations from just one rawAggregation query.

Might create a PR for this at some point, in the meantime feel free to close this and add to your backlog of requests for a future release, if you find my suggestion relevant.

pdphilip commented 2 months ago

I see, I can't imagine that it's too taxing to run them separately but that's not for me to say. Let's leave it open for now, I'll think of a convenience method to run these in one call.

Update to come. Cheers

pdphilip commented 1 month ago

Hi @ftrudeau-pelcro,

There's a new agg() function in the latest release that will do this for you (v2.0.2), Docs: https://opensearch.pdphilip.com/aggregation#grouped-aggregations.

In this example you will run:

 MyLog::where('datetime', '>=', '2024-07-03')->where('datetime', '<=', '2024-07-09')->agg(['max','min','avg'],'runtime');

Cheers