如何让 sqlalchemy/postgres 在全文搜索中使用 GIN 索引

问题描述 投票:0回答:1

所以,我已经使用 Postgres/sqlalchemy 进行全文搜索有一段时间了。没问题,但现在它开始变得很慢,因为表中的项目数量开始变多(例如 600k 项目,这需要大约 10 秒以上)。因此,决定研究一下杜松子酒的索引。

我能够正常创建索引。

问题是,它没有被使用(当我查看 pgAdmin 时进行了 0 次扫描),所以我想知道我做错了什么,或者我是否必须强制使用索引或其他东西。


索引之前的我的表(flask-sqlalchemy 语法):

class Parent_product(db.Model):
    id = ....
    name = db.Column(db.String) 

我会像这样进行搜索(忽略旧的 sqlalchemy 语法):

query = db.session.query(Parent_product)
query = query.order_by(func.similarity(Parent_product.name, search_string).desc())
query = query.filter(func.similarity(Parent_product.name, search_string) > 0.1)
search_results = query.limit(5).all()

然后,我开始实验并在 Parent_product 类中添加了一个索引,如下所示:

__table_args__ = (
    (
    Index(
        'ix_parent_product_name', 
        name,
        postgresql_using="gin",
        postgresql_ops={
            'name': 'gin_trgm_ops',
        }
    )
    ),
)

工作正常,我可以看到索引已在数据库中构建,但如上所述,它没有在相似性查询中使用。

postgresql indexing sqlalchemy full-text-search flask-sqlalchemy
1个回答
0
投票

好吧,我想我明白了。显然,您需要使用所谓的运算符来让 postgres 使用您的索引。

func.similarity
不是运算符,这意味着我必须在搜索查询中将其交换出来,如下所示:

db.session.execute('SET pg_trgm.similarity_threshold = 0.1;')
query = db.session.query(Parent_product)
query = query.filter(Parent_product.name.op("%")(search))
query = query.order_by(Parent_product.name.op("%>")(search).desc())

现在我可以看到正在使用的索引。不太确定我在做什么,但它工作得很快。

© www.soinside.com 2019 - 2024. All rights reserved.