각 테이블이 아닌 UNIFIED QUERY에서 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전체 텍스트를 만들 수 있습니까
  • 점수를 지원하지 않는 IN BOOLEAN 모드 이외의 다른 방법으로 작동합니까?
  • 이 전체 주제에 대한 접근 방식이 있습니까? 임시 테이블을 생성해도 문제가 해결되지 않습니다. MATCH ()의 50 % 규칙 AGAINST ()는 쿼리에서 0 개의 결과를 반환하지만
  • 어쩌면 내가 놓친 것이 있습니까?
  • VIEW 생성도 작동하지 않으며 MySQL은 VIEW에서 INDEX-es를 지원하지 않습니다.
  • IN BOOLEAN MODE를 사용하고 수동으로 스코어링을 생성하는 것이 좋습니다.

이 문제를 해결하기 위해 이틀 이상 일했습니다. 그래서 친절하게 도움을 요청합니다. 감사.

답변:


2

아마도 당신은 세 개의 테이블에서 다음을 기록 할 수 있습니다

  • 테이블 이름
  • 테이블 이름의 열
  • 열의 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 ()를 사용하여 good_score로서 Combined_data의 최종 SELECT는 0 개의 결과를 제공합니다. 이 문제에 대해 조사한 결과 BOOLEAN 모드에서 NON IN BOOLEAN MODE는 50 % 규칙을 적용한다는 사실을 발견했습니다. 이는 50 %의 결과와 수학적인 관계가있을 때 한 테이블의 결과를 무시합니다. 그래도 제안 해 주셔서 감사하지만 다른 아이디어를 듣고 싶습니다. 다시 감사합니다.
dachints
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.