各テーブルではなく、統合クエリから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だけでなく、このようTOPでLEVEL 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フルテキストを作成できますか
  • スコアをサポートしていないインブールモード以外にそれを機能させる方法はありますか
  • このトピック全体を機能させるアプローチはありますか?一時テーブルを作成してもこれは解決されません。MATCH()AGAINST()の50%ルールでは、クエリは0の結果を返しますが、
  • たぶん私が見逃している何かがありますか?
  • VIEWの作成も機能せず、MySQLはVIEWでのINDEX-esをサポートしていません。
  • 多分それはブールモードで使用してスコアリングを手動で作成するのは良い考えですか?

私はこの問題に2日以上取り組んできました。だから私は親切にいくつかの助けを求めます。ありがとう。

回答:


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;

これで、1つのテーブルに対して単一のクエリを実行できます

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

試してみる !!!


私は以前に同様のことをしたことがあり、それはうまくいきませんでした。これも機能しません。MATCH()とAGAINST()を使用したgood_scoreとしての最終的なSELECTEDからの結果は0です。私はこの問題について調査し、NON IN BOOLEAN MODEが50%ルールを適用することを発見しました。このルールは、結果の50%と数学的な関係がある場合、その性質上、1つのテーブルの結果を無視します。それでも提案をありがとうございましたが、他のアイデアも聞きたいです。再度、感謝します。
dachints
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.