首页 > 解决方案 > 加快 PostgreSQL/SQLAlchemy 中的 JSONB 全文搜索

问题描述

使用 PostgreSQL 和 SQLAlchemy,我的 JSONB 全文搜索的性能非常缓慢。我怎样才能加快速度?

模型

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")

标签: pythonpostgresqlsqlalchemyjsonb

解决方案


给定足够的选择性查询,加快全文搜索查询意味着有适当的索引。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))

推荐阅读