Попытка вызвать неопределенный метод с именем "search" из класса "FOS \ ElasticaBundle \ Repository" - PullRequest
0 голосов
/ 14 января 2019

Я хочу использовать метод поиска из хранилища эластики, но я получил ошибку Attempted to call an undefined method named "search" of class "FOS\ElasticaBundle\Repository". Я использую Symfony 4 с пакетом Fosastica, последняя версия. В репо я нахожу метод поиска, но он не возвращает никаких результатов. Я хочу сделать автозаполнение поиска как вы типа как здесь https://www.codevate.com/blog/14-implementing-search-as-you-type-autocomplete-with-elasticsearch-and-symfony

Контроллер:

/**
     * @Route("/search")
     */
    public function searchElastic(RepositoryManagerInterface $finder, Request $request){
        $searchTerm = $request->query->get('s');
        $searchTerm = htmlentities($searchTerm, ENT_QUOTES);

//        $finder = $finder->getRepository(\App\Entity\User::class)->find($searchTerm);
//        return new response(var_dump($finder[0]->getUsername()));

        $completion = new Suggest\Completion('suggest', 'name_suggest');
        $completion->setText($searchTerm);
        $completion->setFuzzy(array('fuzziness' => 2));
        /** var array of App\Entity\User */
        $resultSet = $finder->getRepository(\App\Entity\User::class)->search((Query::create($completion)));
        var_dump($resultSet);
        $suggestions = array();
        foreach ($resultSet->getSuggests() as $suggests) {
            foreach ($suggests as $suggest) {
                foreach ($suggest['options'] as $option) {
                    $suggestions[] = array(
                        'id' => $option['_source']['id'],
                        'username' => $option['_source']['username']
                    );
                }
            }
        }
        return new JsonResponse(array(
            'suggestions' => $suggestions,
        ));
    }

Config:

# Read the documentation: https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/setup.md
fos_elastica:
    clients:
        default: { host: localhost, port: 9200 }
#    indexes:
#        app: ~
    indexes:
        app:
            client: default
#FOR AUTOCOMPLETE
            settings:
                index:
                    analysis:
                        analyzer:
                            name_analyzer:
                                type: custom
                                tokenizer: standard
                                filter: [standard, lowercase, asciifolding, elision]
#END FOR AUTOCOMPLETE
            types:
                user:
                    properties:
#                        username: ~
#                        username:
                        name_suggest:
                          #                    MAPPINGS ADDED FOR AUTOCOMPLETE
                            type: completion
                            analyzer: name_analyzer
                            search_analyzer: name_analyzer
#                            payloads: true
                        id:
                            type: keyword
                        username:
                            type: keyword

#MAPPINGS ADDED FOR AUTOCOMPLETE
                    persistence:
                        # the driver can be orm, mongodb, phpcr or propel
                        # listener and finder are not supported by
                        # propel and should be removed
                        driver: orm
                        model: App\Entity\User
                        provider: ~
                        listener: ~
                        finder: ~


Пользовательское лицо

<?php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use App\Repository\UserRepository;
use Elastica\Search;

/**
 * @UniqueEntity(fields="email", message="Email already taken")
 * @UniqueEntity(fields="username", message="Username already taken")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @Search(repositoryClass="AppBundle\SearchRepository\PropositionRepository")
 */
class User implements UserInterface
{

Пожалуйста, помогите, я новичок в эластике.

UPADTE:

Теперь я получаю эту ошибку.

Cannot autowire argument $finder of "App\Controller\DevController::searchElastic2()": it references class "FOS\ElasticaBundle\Doctrine\RepositoryManager" but no such service exists. Try changing the type-hint to "FOS\ElasticaBundle\Manager\RepositoryManagerInterface" instead.

UPDATE:

Argument 1 passed to App\Repository\UserRepository::__construct() must implement interface Symfony\Bridge\Doctrine\RegistryInterface, instance of FOS\ElasticaBundle\Finder\TransformedFinder given, called in C:\xampp\htdocs\projects\symfonysite\vendor\friendsofsymfony\elastica-bundle\src\Manager\RepositoryManager.php on line 101

UPDATE:

UserRepository.php ссылка

User.php entity ссылка

Контроллер ссылка

** Обновление: **

Я не понимаю. Учебник по ссылке требует функцию поиска, которая отсутствует в моей версии, и функция поиска, которая работает для меня, находит только один результат. Вот простой код, который работает для меня, но найти один результат.

    /**
     * @Route("/search")
     */
    public function searchElastic(RepositoryManagerInterface $finder, Request $request){
        $searchTerm = $request->query->get('s');
        $searchTerm = htmlentities($searchTerm, ENT_QUOTES);

        $finder = $finder->getRepository(\App\Entity\User::class)->find($searchTerm);

        return new response(var_dump($finder[0]->getUsername())); //i tried changing index to 1 but always it return undefined offset

1 Ответ

0 голосов
/ 14 января 2019

Поддержка аннотации поиска была удалена из-за этого объединенного PR , поскольку доступ к хранилищу больше не должен осуществляться через нотацию Bundle: Entity, но запрашивается индекс / тип.

Чтобы использовать пользовательский репозиторий, укажите его в отображении для вашего пользователя, просто добавьте его в строку fos_elastica:

fos_elastica:
    ...
    indexes:
        app:
            client: default
            types:
                user:
                    properties:
                        # your properties
                    persistence:
                        ...
                        repository: App\Repository\UserRepository

Тогда пользовательские запросы будут доступны при использовании репозитория, возвращенного менеджером:

use FOS\ElasticaBundle\Repository;

class UserRepository extends Repository
{
  ...
  function search(RepositoryManagerInterface $finder, Request $request)
    {
    /** var FOS\ElasticaBundle\Manager\RepositoryManagerInterface */
    $repositoryManager = $finder;
    /** var FOS\ElasticaBundle\Repository */
    $repository = $repositoryManager->getRepository(AppEntityUser::class);

    /** var array of Acme\UserBundle\Entity\User */
    $users = $repository->search('bob');
....
...