FriendsOfSymfony / FOSElasticaBundle

Elasticsearch PHP integration for your Symfony project using Elastica.
http://friendsofsymfony.github.io
MIT License
1.25k stars 793 forks source link

How to use search_after with PIT? #1786

Open reypm opened 3 years ago

reypm commented 3 years ago

I need to use pagination and everything that I have used so far is not working for me. Last shoot was with Scroll but it was giving me issues. I decided to use search_after by using a point in time wonder is this two are supported within the bundle or in the underneath ruflin/Elastica package, if so can any provide me with some examples?

lakiboy commented 1 year ago

If somebody is stuck how to use with PIT + search_after here is a short example with generator:

    public function iterate(SomeCriteria $criteria, int $size = 100): Generator
    {
        $pit = $this->index
            ->openPointInTime('3m')
            ->getData()['id']
            ?? throw new RuntimeException('Can not open PIT')
        ;

        $query = $this
            ->criteriaToQuery($criteria)
            ->setPointInTime(new PointInTime($pit, '3m'))
            ->setSort(['field1', 'field2'])
            ->setSize($size)
        ;
        $client = $this->index->getClient();
        $search = new Search($client);

        try {
            do {
                // PIT already contains index information -> search directly on client.
                $result = $search->search($query)->getResults();
                $hasNext = count($result) === $size;

                yield from $result;

                if ($hasNext) {
                    $query = $query->setParam('search_after', $result[$size - 1]->getSort());
                }
            } while ($hasNext);
        } finally {
            $client->closePointInTime($pit);
        }
    }