跨越多行的记录的MATCH相关性(不能将GROUP_CONCAT与MATCH一起使用)

时间:2013-11-07 16:37:30

标签: mysql

我遇到了MySQL问题,我需要一份啤酒午餐。我想做一个这样的查询:

SELECT MATCH(some_string) AGAINST ('beer lunch') FROM (SELECT GROUP_CONCAT(some_column) AS some_string FROM myrealtable) AS mytablealias;

不幸的是,我发现我不能对GROUP_CONCAT列进行FULLTEXT MATCH,因为FULLTEXT索引仅存在于原始列(some_column)而不存在于别名表中的连接列(some_string)中。

我真的需要进行FULLTEXT搜索,并为我表中多行中断的串联字符串生成相关性分数。

这是一个小小的思想实验,我把它放在一起研究相关性问题。让我们从一个具有连接字符串的表开始:

+----------+-------------------------------------------------------------------------------------+
| table_id | concat_string                                                                       |
+----------+-------------------------------------------------------------------------------------+
|        1 | I like beer Beer is a healthy choice My brother drinks beer for lunch every day     |
|        2 | I like juice Juice is a healthier choice My brother drinks beer for lunch every day |
+----------+-------------------------------------------------------------------------------------+

现在,我在此表上执行以下MATCH查询:SELECT table_id,MATCH(concat_string) AGAINST('beer lunch') AS score FROM myconcattable;,我得到以下相关性分数:

+----------+----------------------------+
| table_id | score                      |
+----------+----------------------------+
|        1 | 0.000000007543713209656744 |
|        2 | 0.000000003771856604828372 |
+----------+----------------------------+

显然,在搜索“啤酒午餐”时,第一行与第二行相关性更大......但问题是我的字符串在需要根据外键(foreign_id)分组的多行中被分解。这是我的桌子的真实情况:

+----------+--------------------------------------------+------------+
| table_id | some_string                                | foreign_id |
+----------+--------------------------------------------+------------+
|        1 | I like beer                                |          1 |
|        2 | Beer is a healthy choice                   |          1 |
|        3 | My brother drinks beer for lunch every day |          1 |
|        4 | I like juice                               |          2 |
|        5 | Juice is a healthier choice                |          2 |
|        6 | My brother drinks beer for lunch every day |          2 |
+----------+--------------------------------------------+------------+

现在让我们在这张桌子上尝试查询(SELECT table_id,MATCH(some_string) AGAINST('beer lunch') AS score, foreign_id FROM mybrokentable;):

+----------+----------------------+------------+
| table_id | score                | foreign_id |
+----------+----------------------+------------+
|        1 | 0.031008131802082062 |          1 |
|        2 | 0.031008131802082062 |          1 |
|        3 |  0.25865283608436584 |          1 |
|        4 |                    0 |          2 |
|        5 |                    0 |          2 |
|        6 |  0.25865283608436584 |          2 |
+----------+----------------------+------------+

好的,所以如果我将得分加为总和,那么foreign_id 1看起来比foreign_id 2更有意义,但与将字符串连接成一个表时相比,它不是很准确。

理想情况下,我想设计一个查询,为这样的外国ID生成相关性分数:

+----------------------------+------------+
| score                      | foreign_id |
+----------------------------+------------+
| 0.000000007543713209656744 |          1 |
| 0.000000003771856604828372 |          2 |
+----------------------------+------------+

我应该做些什么的想法?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用子查询对各个短语匹配中的分数进行求和。您必须进行试验,看看它是否能为您提供所需的结果。

SELECT SUM(score) AS total_score,
       foreign_id
  FROM (
     SELECT table_id,
            MATCH(some_string) AGAINST('beer lunch') AS score, 
            foreign_id 
       FROM phrase
       ) AS scores
 GROUP BY foreign_id
 ORDER BY total_score DESC

我在这个小提琴http://sqlfiddle.com/#!2/355b1/1/0中使用了BOOLEAN MODE,因为普通的全文搜索在小的文本样本上使用停用词做奇怪的事情。