Vectorizers

Vectorizers provide means for changing the way how different column types and columns are turned into fulltext search vectors.

Type vectorizers

By default PostgreSQL only knows how to vectorize string columns. If your model contains for example HSTORE column which you would like to fulltext index you need to define special vectorization rule for this.

The easiest way to add a vectorization rule is by using the vectorizer decorator. In the following example we vectorize only the values of all HSTORE typed columns are models may have.

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import HSTORE
from sqlalchemy_searchable import vectorizer


@vectorizer(HSTORE)
def hstore_vectorizer(column):
    return sa.cast(sa.func.avals(column), sa.Text)

The SQLAlchemy clause construct returned by the vectorizer will be used for all fulltext indexed columns that are of type HSTORE. Consider the following model:

class Article(Base):
    __tablename__ = 'article'

    id = sa.Column(sa.Integer)
    name_translations = sa.Column(HSTORE)
    content_translations = sa.Column(HSTORE)

Now SQLAlchemy-Searchable would create the following search trigger for this model (with default configuration)

CREATE FUNCTION
    textitem_search_vector_update() RETURNS TRIGGER AS $$
BEGIN
    NEW.search_vector = to_tsvector(
        'simple',
        concat(
            regexp_replace(
                coalesce(
                    CAST(avals(NEW.name_translations) AS TEXT),
                    ''
                ),
                '[-@.]', ' ', 'g'
            ),
            ' ',
            regexp_replace(
                coalesce(
                    CAST(avals(NEW.content_translations) AS TEXT),
                    ''
                ),
                '[-@.]', ' ', 'g'),
                ' '
            )
        );
    RETURN NEW;
END
$$ LANGUAGE 'plpgsql';

Column vectorizers

Sometimes you may want to set special vectorizer only for specific column. This can be achieved as follows:

class Article(Base):
    __tablename__ = 'article'

    id = sa.Column(sa.Integer)
    name_translations = sa.Column(HSTORE)


@vectorizer(Article.name_translations)
def name_vectorizer(column):
    return sa.cast(sa.func.avals(column), sa.Text)

Note

Column vectorizers always have precedence over type vectorizers.

API

class sqlalchemy_searchable.vectorizers.Vectorizer(type_vectorizers=None, column_vectorizers=None)[source]