Skip to content

Plugin to extend CakePHP Postgres drivers to support Full Text Search

License

Notifications You must be signed in to change notification settings

ionews/cakephp-pg-search

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Busca Textual com PostgreSQL no CakePHP

License CI Coverage Downloads Latest Stable

Adicione suporte a Full Text Search do Postgres em sua aplicação CakePHP.

Requisitos

  • PHP 7.2+
  • CakePHP 4.2.2+
  • PostgreSQL 9.6+

Instalar

Inclua o plugin como dependência

composer require autopage/pg-search

Uso

Para ter todos os recursos disponíveis, você deve configurar sua aplicação para usar o Driver fornecido aqui na conexão com o banco de dados. Ele habilitará o uso do TableSchema e PostgresSchemaDialect incluidos no plugin que estendem as versões padrão do CakePHP para implementar o tipo de coluna tsvector e aos índices do tipo gin e gist.

Configuração

No seu app_local.php:

    // ...
    'Datasources' => [
        'default' => [
            'className' => \Cake\Database\Connection::class,
            'driver' => \Autopage\PgSearch\Database\Driver\Postgres::class,
            // O restante da sua configuração vem normalmente
            // ...
        ],
    // ...

Outra configuração importante, mas opcional, é definir qual configuração de busca o PostgreSQL deve usar na hora de indexar ou buscar um campo do tipo tsvector.

Você pode configurar ela com a chave PgSearch.config_name. Supondo que você criou no seu banco de dados uma configuração de nome portuguese, o seu app_local.php ficaria:

    // ...
    'PgSearch' => [
        'config_name' => 'portuguese',
    ],
    // ...

SearchableBehavior

Associe as tabelas que deseja tornar pesquisável ao behavior, desta forma, sempre que um registro for criado/editado/excluído, as informações serão propagadas para a tabela de busca.

    /**
     * Método de inicialização da Table
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->addBehavior('Searchable', [
            'foreign_key' => 'origem_id',
            'mapper' => function ($entidade) {
                return [
                    'origem_id' => $entidade->id,
                    'conteudo' => $entidade->descricao,
                ];
            },
        ]);
    }

Configurações disponíveis

  • target: string. Nome do repositório (Table) que deve ser usada para persistir os registros de forma pesquisável. Por padrão usa uma Table com nome igual a que está vinculada ao Behavior, adicionado o sufixo 'Searches'. Exemplo: Posts -> PostsSearches.
  • foreign_key: string. Nome da coluna em target que referencia o registro original. Por padrão usa o nome da tabela no singular adicionado o sufixo '_id'. Exemplo: Posts -> post_id
  • mapper: callable. Método/função que converte uma entidade do repositório original para uma de target. Por padrão, ele copia todos os campos da entidade original na entidade nova e associa a chave estrangeira da nova a chave primária da original.
  • doIndex: bool|callable. Se deve ou não indexar o registro. Permite um controle individual. Por padrão o valor é true.
  • doDeindex: bool|callable. Se deve ou não desindexar o registro. Permite um controle individual e suporte a remoção lógica (soft-delete). Por padrão o valor é false.

Finder FTS

O behavior disponibiliza o finder de nome fts. Como todo finder, ele recebe uma query e também retorna uma query. Dessa forma, você pode usar ele para preparar uma query antes ou depois de chamar ele, estendendo as condições e qualquer outra operação possível em uma query.

Os parâmetros especiais desse finder são:

  • field: string (obrigatório). Nome do campo do tipo tsvector onde a busca será feita
  • value: string (obrigatório). Valor que deve ser comparado com o campo
  • highlight: boolean. Flag indicando se deve ou não incluir destaque nos termos encontrados. Por padrão é desativado.
  • highlight_field: string (obrigatório apenas se highlight for true). Nome do campo textual onde o highlight será aplicado
  • exact: boolean. Se a comparação será do tipo exata ou aproximada. Por padrão é aproximada (false).
  • ts_function: string. Caso seja necessário utilizar uma função diferente da aproximada ou exata para parseamento.
  • configuration: string. Nome da configuração de busca usada na comparação. Por padrão, usa a mesma definida em PgSearch.config_name.
  • ranked: boolean. Flag indicando se a query deve ser ordenada por score.

FAQ

Preciso mesmo usar o driver do plugin na minha aplicação?

Não, não precisa. Mas ao não usar, você terá de dizer em cada Table que possui coluna tsvector qual é essa coluna.

Nos seus testes unitários, também não será possível criar Fixture com esse tipo de coluna ou um dos índices gin e gist.

Em resumo: não precisa, mas deveria.

Por que usar uma tabela separada para indexar?

É uma decisão pessoal, tirada após trabalhar com sistemas que migram de backend de busca/indexação ao longo do tempo. Separar as tabelas te fornece mais flexibilidade. E o tradeoff é o uso um pouco maior de disco.

Essa tabela indexada pode ser uma versão desnormalizada de outra, permitindo que você faça várias consultas que exigiriam joins e subqueries de outra maneira. Em um segundo momento, quando passar a ter bilhões de registros, você pode querer desacoplar essa tabela do banco principal e passar para uma outra instância, ou mesmo para um serviço especializado como Elasticsearch, Solr e Sphinx.

Entendi, mas posso usar a mesma tabela do registro principal?

Até pode, mas você ganharia apenas o finder como vantagem - os recursos de sincronização ficam desativados.

About

Plugin to extend CakePHP Postgres drivers to support Full Text Search

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages