Как правильно добавить пользовательское свойство в определенный тип

В поле поиска я хочу предложить пользователям города, в которых имена сортируются по количеству найденных ресторанов (в порядке убывания).

Поэтому я хочу добавить настраиваемое поле, которое поможет мне отсортировать названия городов (например, "Вашингтон" => в Арканзасе, Иллинойсе, Калифорнии и т. Д.) По количеству ресторанов.

Я прочитал следующую кулинарную книгу, чтобы добавить пользовательское свойство, но мое отсутствие знаний в sf и эластика не позволяет мне поставить слушателя в нужное место.

Допустим, у меня есть city и restaurant наберите, настройте так:

city:
  mappings:
    name: ~
    location: { type: geo_point }
restaurant:
  mappings:
    name: ~
    location: { type: geo_point }

Я знаю, что для каждого города, добавленного в мой индекс, я должен определять местоположение каждого близлежащего ресторана (например, ~ 5 миль). Как я должен это делать?

контекст:

  • php 5.6
  • Symfony 2.3
  • friendsofsymfony /astica-bundle 3.1.x

1 ответ

Решение

Я отвечу на мой вопрос, если это может помочь:

Если вы хотите геолокации (или делать какие-либо другие операции) на конкретный тип, вам просто нужно отфильтровать его:

// assume correct namespaces are used...
class CustomPropertyListener implements EventSubscriberInterface
{
    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function addCustomProperty(TransformEvent $event)
    {
        if ($event->getDocument()->getType() === 'city') {

            $coord = $event->getDocument()->get('location');
            // call to the service which can find restaurants 
            $finder = $this->container->get('fos_elastica.finder.restaurant');            
            $filter = new GeoDistance('location', $coord, '5mi');

            $all = new Query(new MatchAll());
            $query = new Filtered($all, $filter);
            $entities = $finder->find($query);

            $document->set('numRestaurants', count($entities));
        }
    }
}

$container определяется в services файл определения. Например, в YAML:

    acme.listener.custom_property:
    class: AcmeBundle\EventListener\CustomPropertyListener
    arguments: ['@service_container']
    tags:
        - { name: kernel.event_subscriber }

Следует отметить, что elastic + elastica-bundle плохо документированы для такого сложного и критического компонента. Большая часть важной информации разбросана по сети или в коде. Я надеюсь, что разработчики знают об этом!

Другие вопросы по тегам