Ускорьте полнотекстовый поиск JSONB в PostgreSQL / SQLAlchemy - PullRequest
0 голосов
/ 20 апреля 2019

Производительность моего полнотекстового поиска JSONB очень низка с использованием PostgreSQL и SQLAlchemy. Как я могу ускорить это?

Модель

class Book(Base):
    __tablename__ = "book"
    id = Column(Integer, primary_key=True)
    jsondata = Column(JSONB)
    __table_args__ = (Index('index_jsondesc',
                      text("(jsondata->'description') jsonb_path_ops"),
                      postgresql_using="gin"),)

Полнотекстовый поиск в столбце JSONB

class BookSearch:
    def __init__(self):
        pass
    def search(keyword):
        self.query = self.query.filter(Book.jsondata['description'].cast(Unicode).match(keyword))

booksearch = BookSearch()
booksearch.search("Python")

1 Ответ

1 голос
/ 21 апреля 2019

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

Класс операторов GIN не по умолчанию jsonb_path_ops поддерживает индексирование только оператора @>.

Вместо этого вам нужен (например) функциональный индекс для явного to_tsvector():

class Book(Base):
    __tablename__ = "book"
    id = Column(Integer, primary_key=True)
    jsondata = Column(JSONB)
    __table_args__ = (
        Index('index_jsondesc',
              func.to_tsvector('english', jsondata['description'].astext),
              postgresql_using="gin"),
    )

Обратите внимание, что вы должны выбрать конфигурацию, которая будет использоваться при определении индекса. Ваш запрос должен соответствовать конфигурации, используемой в индексе:

def search(keyword):
    tsvector = func.to_tsvector('english', Book.jsondata['description'].astext)
    self.query = self.query.filter(tsvector.match(keyword))
...