# Smart Segments

{% hint style="success" %}
This is the official documentation of the `forestadmin/laravel-forestadmin` v2+ and `forestadmin/symfony-forestadmin` PHP agents.
{% endhint %}

Smart Segments should be quick to migrate, as the syntax is very similar to the legacy agent.

{% hint style="info" %}
You can find the full documentation of segment customization [here](/developer-guide-agents-php/agent-customization/segments.md).
{% endhint %}

## How to migrate

### Structure

Because the new Forest Admin agent is designed to work with multiple databases, the return value of the filter function is not a Sequelize or Mongoose condition anymore.

Instead, you'll be building a [condition tree](/developer-guide-agents-php/data-sources/getting-started/queries/filters.md#condition-trees) that will be translated to the appropriate database syntax by the agent.

### Performance

All queries cannot be expressed in the Forest Admin query interface, but many can.

You can have great performance improvements by using the Forest Admin query interface to build your conditions, instead of performing the query yourself, and then building a naive condition tree, which filters by primary key like in the example we're providing.

### Example

In this example, we migrate a segment that returns the 5 bestsellers of a product collection.

{% tabs %}
{% tab title="Before" %}

```php
<?php

namespace App\Models;

use ForestAdmin\LaravelForestAdmin\Services\Concerns\ForestCollection;
use ForestAdmin\LaravelForestAdmin\Services\SmartFeatures\SmartSegment;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory
    use ForestCollection;

    /**
     * @return SmartSegment
     */
    public function bestSellers(): SmartSegment
    {
        return $this->smartSegment(
            fn(Builder $query) => $query->whereIn('products.id', function($q) {
                $q->select('products.id')
                    ->from('products')
                    ->join('order_product', 'order_product.product_id', '=', 'products.id')
                    ->groupBy('products.id')
                    ->orderByRaw('COUNT(order_product.order_id) DESC')
                    ->limit(10);
            }),
            'Best sellers'
        );
    }
```

{% endtab %}

{% tab title="After" %}

```php
$forestAgent->customizeCollection(
    'Product',
    function (CollectionCustomizer $builder) {
        $builder->addSegment(
            'bestSellers',
            function (CollectionCustomizationContext $context, ResultBuilder $resultBuilder) {
                $rows = $context->getDatasource()->getCollection('Order')->aggregate(
                    new Filter(),
                    new Aggregation(operation: 'Count', groups: [['field' => 'product_id']]),
                    10
                );

                return $resultBuilder->value($rows);
            }
        );
    }
);
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestadmin.com/developer-guide-agents-php/getting-started/migrating/code-transformations/smart-segments.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
