Я хочу использовать метод поиска из репозитория elastica, но получил ошибку
Attempted to call an undefined method named "search" of class "FOS\ElasticaBundle\Repository".
Я использую Symfony 4 с последней версией пакета fos elastica. В репо я работаю методом поиска, но он не возвращает никаких результатов.
Я хочу выполнить поиск по типу автозаполнения, как здесь 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,
));
}
Конфиг:
# 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
{
Пожалуйста, помогите, я новичок в эластике.
ОБНОВЛЕНИЕ:
Теперь я получаю эту ошибку.
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.
Обновлено:
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
Обновлено:
UserRepository.php ссылка
Сущность User.php ссылка
Контроллер ссылка
**Обновлять: **
Я не понимаю. Учебник в ссылке требует функции поиска, которой нет в моей версии, и функции поиска, которая работает для меня, находит только один результат. Вот простой код, который у меня работает, но есть один результат.
/**
* @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
Класс Repository не имеет метода search(). Упомянутый вами учебник называется search() на экземпляре Elastica\Index.




Поддержка аннотации Search была удалена из-за этого объединенного 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');
....
@ user10567054 попробуйте тоже посмотреть мое обновление. Я кое-что упустил. Вам нужно использовать RepositoryManagerInterface для автозапуска для доступа к вашему репозиторию.
ваш UserRepository должен расширять FOS\ElasticaBundle\Repository взгляните на мой код ... не могли бы вы показать мне свой класс UserRepository
Я добавил, но это ничего не меняет. Ссылки в обновлении.
Не могли бы вы показать мне этот класс AppBundle\SearchRepository\PropositionRepository и очистить кеш, пожалуйста
У меня нет хранилища предложений. Кэш очистю. посмотри на обновление
AppBundle\SearchRepository\PropositionRepository - это не то, что у меня есть, я копирую и вставляю это, после замены на @Search(repositoryClass = "AppBundle\SearchRepository\UserRepository") никаких изменений. Стоит ли писать сюда App/Repository/UserRepository?
хммм какое репо содержит функцию search()?
Я думал, что это функция elastica, а не моя функция репо. Я хотел сделать это как в codevate.com/blog/…, но у меня последняя версия, которая не такая.
Оооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо
Я думаю, вам не нужно использовать репозиторий, и вы пропустите объяснение своей проблемы. Вы можете просто ввести PaginatedFinderInterface , а затем вызвать метод search ()
ошибка из приведенного выше кода - Cannot autowire argument $finder of "App\Controller\DevController::searchElastic2()": it references interface "FOS\ElasticaBundle\Finder\PaginatedFinderInterface" but no such service exists. You should maybe alias this interface to the existing "fos_elastica.finder.app.user" service.
Да, вы можете определить правильные аргументы в своем DevController ... не могу вам помочь, извините. вам следует вернуться к fos doc и посмотреть, как вы определяете службу аргументов
Где я могу найти документы? Я очень хочу этим заниматься. Почему не работает, пока я делаю именно так, как в ссылке?
Хорошо, я нашел документ github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/do c
Почему нет метода поиска ?! Есть только находка, которая у меня сработала. github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/do c /…
найти объект возврата ydrateted, поиск вернуть формат json и использовать поиск, я думаю, вам следует ввести Elastica\Type
А можно попробовать воткнуть
FOS\ElasticaBundle\Doctrine\RepositoryManagerвместо своегоRepositoryManagerInterface?