不为每个表从统一查询中计算MATCH()AGAINST()分数


10

我正在尝试对SELECT语句的整个部分进行评分

SELECT *,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
UNION
SELECT *,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
UNION
SELECT *,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')

在这种情况下,分数是每张桌子的分数+它们不是按相关性排序的

但是我尝试了这种方法,这种方法虽然有效,但不值得生产

SELECT * FROM (
    SELECT *,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
    UNION
    SELECT *,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
    UNION
    SELECT *,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')
) as `combined` ORDER BY `score` DESC

上面的代码是不受欢迎的,因为每个表都有分数,它们是按顺序排列的。不好的方法。

于是,我就MATCH() AGAINST()data在顶级SELECT以及这一点。(不工作)

SELECT *,MATCH(`data`) AGAINST('keyword') as `good_score` FROM (
        SELECT *,`result` as `data`,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
        UNION
        SELECT *,`content` as `data`,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
        UNION
        SELECT *,`text` as `data`,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')
    ) as `combined` ORDER BY `good_score` DESC

上面的语句对我来说是完美的,但是它不起作用,因为该data列是即时创建的,并且不支持具有FULLTEXT INDEX。

我的问题是如何继续使发动机运转。

  • 你能以某种方式使data一个FULLTEXT
  • 除了不支持得分的IN BOOLEAN MODE之外,还有其他方法可以使它工作吗
  • 是否有一种方法可以解决整个主题?创建临时表不能解决此问题,MATCH()AGAINST()的50%规则会使查询返回0个结果,但是有很多结果
  • 也许我想念一些东西?
  • 创建VIEW也不起作用,MySQL不支持VIEW上的INDEX-es。
  • 使用IN BOOLEAN MODE并手动创建计分也许是个好主意?

我已经为这个问题工作了两天以上。因此,请您提供一些帮助。谢谢。

Answers:


2

也许您可以从三(3)个表中记录以下内容

  • 表名
  • 表名称中的列
  • 列上的FULLTEXT索引

这是代码:

DROP TABLE IF EXISTS combined_data;
CREATE TABLE combined_data
(
    source_table VARCHAR(64),
    source_id INT NOT NULL,
    data TEXT NOT NULL,
    FULLTEXT (data)
) ENGINE=MyISAM;
--
ALTER TABLE combined_data DISABLE KEYS;
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table1',id,`result` FROM table1 WHERE MATCH(`result`) AGAINST('keyword');
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table2',id,`content` FROM table1 WHERE MATCH(`content`) AGAINST('keyword');
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table3',id,`text` FROM table1 WHERE MATCH(`text`) AGAINST('keyword');
--
ALTER TABLE combined_data ENABLE KEYS;

现在您可以对一个表运行单个查询

SELECT *,MATCH(`data`) AGAINST('keyword') as `good_score`
FROM combined_data
ORDER BY `good_score` DESC;

试试看 !!!


我之前做过类似的事情,但没有成功。这一项也不起作用。使用MATCH()和AGAINST()从combined_data作为good_score进行的最终选择给出0结果。我对此问题进行了研究,发现NON IN BOOLEAN MODE应用了50%规则,从本质上讲,当与50%的结果存在某种数学关系时,它会以某种方式忽略一张表的结果。不过,还是谢谢您的建议,但我想听听其他想法。再次感谢。
dachints 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.