Using document_field filter

> Important! This documentation is based on the 1.x version of the bundle The documentation update is in process

This example will provide real use case of document_field filter. Two different document types will be created: country and city. Every city will contain id of country. We want to display page for country and list cities in that country.

Configuration

First of Elasticsearch, FilterManager and Router bundles have to be configured.

 # app/config/config.yml
 
ongr_elasticsearch:
    analysis:
        analyzer:
            urlAnalyzer:
                type: custom
                tokenizer: keyword
                filter: [lowercase]
    connections:
        default:
            hosts:
                - 127.0.0.1:9200
            index_name: world
            analysis:
                analyzer:
                    - urlAnalyzer
            settings:
                number_of_shards: 1
                number_of_replicas: 0
                index:
                    refresh_interval: -1
    managers:
        default:
            connection: default
            profiler: true
            mappings:
                - AppBundle
                
ongr_filter_manager:
    managers:
        cities_list:
            filters:
                - country_filter
            repository: 'es.manager.default.city'
    filters:
        document_field:
            country_filter:
                request_field: document
                field: country_id

ongr_router:
    es_manager: default
    seo_routes:
        Country:
            _route: country_page
            _controller: AppBundle:Default:countryPage
            _id_param: _id
            _default_route: homepage

Define documents

Next step is to define documents:

// src/AppBundle/Document/Country.php
    
namespace AppBundle\Document;

use ONGR\ElasticsearchBundle\Annotation as ES;
use ONGR\RouterBundle\Document\SeoAwareTrait;

/**
 * @ES\Document(type="country")
 */
class Country
{
    use SeoAwareTrait;

    /**
     * @ES\Property(type="string", options={"index"="not_analyzed"})
     */
    public $name;
}
// src/AppBundle/Document/City.php

namespace AppBundle\Document;

use ONGR\ElasticsearchBundle\Annotation as ES;

/**
 * @ES\Document(type="city")
 */
class City
{
    /**
     * @ES\Property(type="string", options={"index"="not_analyzed"})
     */
    public $name;

    /**
     * @ES\Property(type="string", options={"index"="not_analyzed"})
     */
    public $countryId;
}

Importing sample data

This step is here only for demonstration purposes.

Create file countries.json with following content:

[
{"count":8,"date":"2015-12-16T11:47:22+0200"},
{"_type":"country","_id":"2","_source":{"name":"USA","urls":[{"url":"country\/USA\/"}],"expired_urls":[]}},
{"_type":"city","_id":"a","_source":{"name":"Miami","country_id":2}},
{"_type":"city","_id":"b","_source":{"name":"New York","country_id":2}},
{"_type":"city","_id":"c","_source":{"name":"San Francisco","country_id":2}},
{"_type":"country","_id":"1","_source":{"name":"Germany","urls":[{"url":"country\/Germany\/"}],"expired_urls":[]}},
{"_type":"city","_id":"d","_source":{"name":"Berlin","country_id":1}},
{"_type":"city","_id":"e","_source":{"name":"Munich","country_id":1}},
{"_type":"city","_id":"f","_source":{"name":"Hamburg","country_id":1}}
]

To import this data run app/console ongr:es:index:import countries.json.

Using filter

Last step is to use created filter. Custom action will be created:

// src/AppBundle/Controller/DefaultController.php

namespace AppBundle\Controller;

use AppBundle\Document\Country;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /**
     * @Route("/countryPage/{country}", name="country_page")
     */
    public function countryPageAction(Country $document, Request $request)
    {
        $manager = $this->get('ongr_filter_manager.cities_list');

        $cities = [];

        foreach ($manager->handleRequest($request)->getResult() as $city) {
            $cities[] = $city->name;
        }

        return new Response('Cities in ' . $document->name . ': ' . implode(', ', $cities));
    }
}

Now if you go to example.com/country/Germany/ you should see:

Cities in Germany: Berlin, Munich, Hamburg

Response at example.com/country/USA/ should be:

Cities in USA: Miami, New York, San Francisco