1

我目前正在尝试使用 pg_trgm 操作%<->. 列上的 GIN 索引已经可用,但我找不到与前面提到的运算符等效的 sqlalchemy。

除了编写纯文本查询之外,解决此问题的最佳方法是什么。

一个简单的示例查询是:

tag = test
tag_subq = session.query(sticker_tag.file_id, f'sticker_tag.name <-> {tag}'.label(distance)) \
    .filter(f'sticker_tag.name % {tag}')) \
    .filter('distance' < 0.3) \
    .subquery("tag_subq")

上面的查询显然不起作用,选择和过滤字符串只是占位符,用于可视化我打算做什么。

4

3 回答 3

6

您可以使用Operators.op()方法;这会生成您需要的任何运算符:

sticker_tag.name.op('<->')(tag)
sticker_tag.name.op('%%')(tag)

百分比运算符加倍以对其进行转义,因为 python dbapi 使用 %foo 或 %(foo) 语法将参数插入查询。

于 2018-10-24T11:10:10.890 回答
4

对于使用 Postgres 的人,可以使用它来similarity代替。

注意:请记住pg_trgm首先在 Postgres 中安装扩展:CREATE EXTENSION pg_trgm;

这是使用 SQLAlchemy 的示例:

# ... other imports
from sqlalchemy import and_, func, or_

def search_store_product(search_string: str) -> Optional[list[Product]]:
    try:
        return session.query(Product).filter(
            or_(
                func.similarity(Product.name, search_string) > 0.6,
                func.similarity(Product.brand, search_string) > 0.4,
            ),
            and_(Product.updated_on >= datetime.utcnow() - timedelta(days=5)),
        ).order_by(Product.created_on).limit(20).all()

    except ProgrammingError as exception:
        logger.exception(exception)
        raise

    finally:
        session.close()
于 2021-08-07T04:45:31.213 回答
0

如果有人感兴趣,我做了一些比较%方法和similarity(...) > x方法的测试,使用%. 在某些情况下超过 10 倍。

SELECT * FROM X WHERE name % 'foo';

SELECT name FROM x WHERE similarity(name, 'foo') > 0.7;

因此,如果它与您的查询相关,我建议仅在语句中使用该similarity(..)函数。SELECT像这样:

SELECT name, similarity(name, 'foo') FROM X WHERE name % 'foo';

但是你需要pg_trgm.similarity_threshold在使用前进行设置,%因为默认值为 0.3,在我看来这对于大多数应用程序来说太模糊和太慢了。所以rmn的回答更可取,只记得设置similarity_threshold每个会话!

在 SQL Alchemy 中会是这样的

db.session.execute('SET pg_trgm.similarity_threshold = 0.7;')
items = Model.query.filter(Model.name.op("%")(name)).all()
于 2022-02-16T18:44:47.357 回答