3
votes

I'm trying to make a search sorted by proximity with elasticsearch. I installed FOSElasticaBundle and I have this configuration on my config.yml:

fos_elastica:
    clients:
        default: { host: localhost, port: 9200 }
    serializer:
        callback_class: FOS\ElasticaBundle\Serializer\Callback
        serializer: serializer
    indexes:
        productos:
            client: default
            settings:
                index:
                  analysis:
                        analyzer:
                            default:
                                type: spanish
                                tokenizer: icu_tokenizer
                                filter: [ icu_folding, my_ngram ]
                        filter:
                            my_ngram:
                                type: "nGram"
                                min_gram: 2
                                max_gram: 25
            types:
                producto:
                    mappings:
                        nombre: { boost: 5 }
                        descripcion: { boost: 3 }
                    persistence:
                        driver: orm
                        model: Gupost\BackendBundle\Entity\Producto
                        listener:
                        provider: ~
                        finder: ~
        comercios:
            client: default
            settings:
                index:
                  analysis:
                        analyzer:
                            default:
                                type: spanish
                                tokenizer: icu_tokenizer
                                filter: [ icu_folding, my_ngram ]
                        filter:
                            my_ngram:
                                type: "nGram"
                                min_gram: 2
                                max_gram: 25
            types:
                comercio:
                    mappings:
                        nombrecomercio: { boost: 5 }
                        razonsocial: { boost: 5 }
                        location: {type: geo_point}

                    persistence:
                        driver: orm
                        model: Gupost\BackendBundle\Entity\Comercio
                        listener:
                        provider: ~
                        finder: ~

The index is built correctly and if I execute this query:

curl -XGET 'http://localhost:9200/comercios/comercio/_search' -d '{
    "query": {
        "filtered" : {
            "query" : {
                "match_all" : {}
            },
            "filter" : {
                "geo_distance" : {
                    "distance" : "100m",
                    "location" : {
                        "lat" : -2.1741771697998047,
                        "lon" : 43.28249657890983
                    }
                }
            }
        }
    }

}'

I got some results. The problem is when I'm trying to get the results form my controller.
How can I do that? I tried with this:

<?php

namespace Acme\ApiBundle\Controller;

use Elastica\Query\Filtered;
use FOS\RestBundle\Controller\Annotations\NamePrefix;       // NamePrefix Route annotation class @NamePrefix("bdk_core_user_userrest_")
use FOS\RestBundle\View\RouteRedirectView;                  // Route based redirect implementation
use FOS\RestBundle\View\View AS FOSView;                    // Default View implementation.
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\ConstraintViolation;
use FOS\RestBundle\Request\ParamFetcher;
use FOS\RestBundle\Controller\Annotations\RequestParam;
use Elastica\Filter\GeoDistance;
use Elastica\Query;
use Elastica\Query\MatchAll;
//use Elastica\Query\F
/**
 * Controller that provides Restful sercies over the resource Users.
 *
 * @NamePrefix("api_rest_comercios")
 */
class ComerciosRestController extends Controller
{

    public function getgeocomerciosAction() {
        $view = FOSView::create();
        $finder = $this->container->get('fos_elastica.finder.comercios.comercio');

        $query = new Query();

        $filter = new GeoDistance('location', array('lat' => -2.1741771697998047,
             'lon' => 43.28249657890983), '100m');
        $all = new Query(new MatchAll());
        $query = new Filtered($all, $filter);

        $data = $query->toArray();
        ladybug_dump( $data );
        $query->setRawQuery($data);
        $entities = $finder->find($query);
        // $results = $index->search($query);

        if ($entities) {
            $view->setStatusCode(200)->setData($entities);
        }
        return $view;
    }
}

But it's not working. I get this error:

Catchable Fatal Error: Argument 1 passed to Elastica\Query\Filtered::__construct() must be an instance of Elastica\Query\AbstractQuery, instance of Elastica\Query given, called in /Users/gitek/www/merkaklub/src/Gupost/ApiBundle/Controller/ComerciosRestController.php on line 92 and defined in /Users/gitek/www/merkaklub/vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php line 36

Any help or clue?

1
I do not try it but what about $query = new Filtered(new MatchAll(), $filter);?LFI
it works with $query = new Filtered(new MatchAll(), $filter); $entities = $finder->find($query); thx!!! can you answer my question to give you the correct answer? thx!Kioko Kiaza

1 Answers

4
votes

The correct code is

$query = new Filtered(new MatchAll(), $filter);

as \Elastica\Query\MatchAll extends AbstractQuery. \Elastica\Query is a kind of client with a quite confusing name.