在 sqlite fts5 查询中使用 Match 但需要更多地控制排名?

Posted

技术标签:

【中文标题】在 sqlite fts5 查询中使用 Match 但需要更多地控制排名?【英文标题】:Using Match in a sqlite fts5 query but need more control over ranking? 【发布时间】:2018-10-11 18:59:49 【问题描述】:

我有一个使用 fts5 创建的虚拟表:

import sqlite3
# create a db in memory
con = sqlite3.connect(':memory:')
con.execute('create virtual table operators using fts5(family, operator, label, summary, tokenize=porter)')

# some sample data
samples = 'insideTOP':
              'label':'Inside',
               'family':'TOP',
               'summary':'The Inside TOP places Input1 inside Input2.'
              ,
           'inTOP':
              'label':'In',
               'family':'TOP',
               'summary':'The In TOP is used to create a TOP input.'
              ,
           'fileinSOP':
              'label':'File In',
               'family':'SOP',
               'summary':'The File In SOP allows you to read a file'
              
          

# fill db with those values
for operator in samples.keys():
    opDescr = samples[operator]
    con.executescript("insert into operators (family, operator, label, summary) values ('0','1','2','3');".format(opDescr['family'],operator,opDescr['label'],opDescr['summary']))

有以下列

+--------+-----------+------------+----------------------------------------------+
| family | operator  |   label    |            summary                           |
+--------+-----------+------------+----------------------------------------------+
| TOP    | insideTOP | Inside     | The Inside TOP places Input1 inside Input2.|
| TOP    | inTOP     | In         | The In TOP is used to create a TOP input.    |
| SOP    | fileinSOP | File In    | The File In SOP allows you to read a file    |
+--------+-----------+------------+----------------------------------------------+

一个示例查询是:

# query the db
query = "select operator from operators where operators match 'operator:In*' or operators match 'label:In*' order by family, bm25(operators)"
result = con.execute(query)

for row in result:
    print(row)

结果我得到了

文件 SOP 在顶部 在顶部

但对于这种特殊情况,我实际上希望“inTOP”出现在“insideTOP”之前,因为标签是完美匹配的。

什么是能够以我想要的方式按摩这些结果的好方法?

非常感谢

马库斯

【问题讨论】:

能否分享您的数据库设置,以便我们更轻松地复制您的情况? operator 列在label 之前检查匹配,因此您的“完美匹配”可能甚至不会在查询中查看。 @Corion - 我为此添加了一个示例脚本。 @Shawn - 谢谢!我颠倒了顺序,但结果没有改变。 如果您查看 bm25(operators) 为您的结果返回的内容,您会看到两个 TOP 行具有相同的值,因此它们的顺序将是任意的(可能是它们被插入的顺序桌子)。如果您将标签添加到 ORDER BY 列表的末尾,则较短的将首先排序。 【参考方案1】:

也许您可以将您的订单规则放在问题中。

如果你使用 bm25 来排序你的结果,你无法达到你想要的结果 我建议你可以使用自定义排名函数,如下 sql:

query = "select operator from operators where operators match 'operator:In*' or operators match 'label:In*' order by myrank(family, operators)"

在 fts5 中定义自定义排名函数非常简单,您可以按照 fts5 网站中的指南进行操作。

如果你也想要bm25结果作为排名分数,你可以在rank方法中得到分数,可以计算你的最终分数。

【讨论】:

以上是关于在 sqlite fts5 查询中使用 Match 但需要更多地控制排名?的主要内容,如果未能解决你的问题,请参考以下文章

Sqlite FTS5 标点符号在选择查询中不起作用

Peewee 可以使用 SQLite 的 FTS5(全文搜索)辅助函数 highlight() 吗?

如何在 Peewee 和 SQLite 的 FTS5 中使用 trigram tokenizer/similarity 选项?

如何使用带有 Python 3.7 的 sqlite3 python 模块的 FTS5 扩展?

C# SQLite FTS5 表和触发器创建

如何在 Ubuntu 16.04 上将 FTS5 扩展与带有 Python 3.7 的 sqlite3 python 模块一起使用?