在MySQL中搜索短语关键字

时间:2015-05-16 13:46:29

标签: python mysql regex search phrase

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

  • 汽车
  • 汽车销售
  • 汽车
  • 跑车
  • Sports foo
  • Car bar
  • 统计

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

"Find sports car sales statistics in Manhattan."

我正在寻找(我已经搜索了很长一段时间)找到一个MySQL查询或一个接收给定输入的算法,并检测keywords列中使用的关键字,产生的结果为:

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

换句话说,我试图以句子的形式输入一个输入,然后匹配数据库中找到的所有现有(和最相关)关键字值。句子。请注意,这些关键字可以是由空格分隔的单词组成的短语。

经过研究,我发现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)

我也尝试改进相关性,但这只会返回一条记录:

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

1 个答案:

答案 0 :(得分:1)

如果我们假设您将列中的列作为此类任务的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

注意:如果您的列为小写,则以下set comprehension将转换元素:

>>> 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'])

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