在 MySQL 中搜索短语关键字

Searching for Phrase Keywords in MySQL

我有一个 table,它有两列:ID(主键,自动递增)和 keyword(文本,全文索引)。 在 keyword 列中输入的值包括以下内容: 关键字

假设我们将这句话作为输入:

"Find sports car sales statistics in Manhattan."

我正在寻找(而且我已经搜索了很长一段时间)来查找 MySQL 查询或接受给定输入并检测 [=19] 中使用的关键字的算法=] 列,导致输出:

"Sports cars", "Car sales", "Statistics"

换句话说,我正在尝试采用句子形式的输入,然后匹配数据库中在该句子中找到的所有现有(和最相关)关键字值。请注意,这些关键字可能是由 space.

分隔的单词组成的短语

经过研究,我了解到 MySQL 通过其全文搜索功能做类似的工作。我尝试了所有自然语言、布尔值和查询扩展选项,但它们包含的关键字记录只有一半内容与输入匹配。例如,它输出:

"Car", "Car sales", "Sports cars", "Sports foo", "Cars bar", "Statistics".

我不希望发生这种情况,因为它包含输入中甚至没有的词(即 foo 和 bar)。

这是上述搜索的 MySQL 查询:

SELECT * FROM tags WHERE MATCH(keyword) AGAINST('Find sports car sales statistics in Manhattan.' IN BOOLEAN MODE)

我也尝试过提高相关性,但是这个只有 returns 一条记录:

SELECT *, SUM(MATCH(keyword) AGAINST('Find sports car sales statistics in Manhattan.' IN BOOLEAN MODE)) as score FROM tags WHERE MATCH(keyword) AGAINST('Find sports car sales statistics in Manhattan.' IN BOOLEAN MODE) ORDER BY score DESC

如果我们假设您将列表中的列作为执行此类任务的 pythonic 方式,您可以使用 set.intersection 获取两个集合之间的交集(第二个元素可以是另一个可迭代对象,如列表或元组) :

>>> col={'Car','Car sales','Cars','Sports cars','Sports foo','Car bar','Statistics'}
>>> col={i.lower() for i in col}
>>> s="Find sports car sales statistics in Manhattan."
>>> col.intersection(s.strip('.').split())
set(['car', 'statistics'])

在您的情况下,您可以将查询结果放在 set 中或将其转换为 set

注意:如果您的列为小写,则以下集合理解将转换元素:

>>> col={i.lower() for i in col}

但是这个秘诀会找到你的列和带有空格的拆分字符串之间的交集。所以结果将是:

set(['car', 'statistics'])

作为另一种方式,您可以使用 re.search :

>>> col={'Car','Car sales','Cars','Sports cars','Sports foo','Car bar','Statistics'} 
>>> s='Find sports car sales statistics in Manhattan.'
>>> for i in col:
...    g=re.search('{}'.format(i),s,re.IGNORECASE)
...    if g:
...      print g.group(0)
... 
statistics
car sales
car

作为一种简单的方法,您可以使用如下函数来获得短语的组合:

from itertools import permutations
def combs(phrase):
    sp=phrase.split()
    com1=[map(lambda x:' '.join(x),li) for li in [permutations(sp,j) for j in range(1,len(sp)+1)]]
    for i,k in enumerate(sp):
          if not k.endswith('s'):
             sp[i]=k+'s'
    com2=[map(lambda x:' '.join(x),li) for li in [permutations(sp,j) for j in range(1,len(sp)+1)]]
    return com1+com2

print {j for i in combs('Car sales') for j in i}
set(['Car', 'sales', 'sales Cars', 'Car sales', 'Cars sales', 'sales Car', 'Cars'])

请注意,此功能可以更加高效和完整。