0

OK、スコアリングされた結果を返す素敵な小さなクエリができました。クエリは現在ベースであり、誰もが私に言い続けLIKEているように、フルテキスト クエリに変換したいと考えています。同じスコアではない場合でも、同じ結果の順序を取得したいと思います。何かを近づけることができた唯一の方法は、クロス結合を展開することです...

  • 特定の単語の組み合わせに対してスコアを設定できるようにしたい
  • 用語が見つかった場所に基づいて重みを設定できるようにしたい
  • 検索の単語のパワーセットに基づいて検索したくありません。つまり、ユーザーが「鉄道の従業員」と入力した場合、「従業員」を検索したくありません。クエリから単語の連続したグループのみを検索しようとしています。

元のクエリを全文ベースにし、比較的小さく整理するにはどうすればよいですか?

SQLFiddleで両方のクエリを確認できます。

元のクエリ- スコアと検索語がすべて 1 か所にまとめられています

SELECT
  sum(score * multiplier) score,
  a.id,
  a.title
FROM
(
  SELECT 3 score, 'a railway employee' term UNION ALL
  SELECT 2 score, 'railway employee' term UNION ALL
  SELECT 2 score, 'a railway' term UNION ALL
  SELECT 1 score, 'employee' term UNION ALL
  SELECT 1 score, 'railway' term UNION ALL
  SELECT 0 score, 'a' term
) terms
CROSS JOIN
(
  SELECT 'T' TYPE, 1 multiplier
  UNION ALL SELECT 'S', 1.1
  UNION ALL SELECT 'C', 1.5
) x
INNER JOIN
(
  SELECT id, 'T' TYPE, title SEARCH FROM articles
  UNION ALL
  SELECT id, 'S' TYPE, summary SEARCH FROM articles WHERE summary <> ''
  UNION ALL
  SELECT artId, 'C' TYPE, content SEARCH FROM articleSections
) s ON s.TYPE = x.TYPE AND SEARCH LIKE concat('%', terms.term, '%')
INNER JOIN articles a ON a.id = s.id
WHERE score > 0
GROUP BY id, title
ORDER BY score DESC, title;
;

全文- 乱雑で大きく、スコアと検索語があちこちに散らばっています

SELECT
  sum(score * multiplier) score,
  id,
  title
FROM
(
SELECT
  3 score,
  1 multiplier,
  'T' AS loc,
  id,
  title
FROM articles
WHERE MATCH(title) AGAINST ('"a railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1 multiplier,
  'T' AS loc,
  id,
  title
FROM articles
WHERE MATCH(title) AGAINST ('"railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1 multiplier,
  'T' AS loc,
  id,
  title
FROM articles
WHERE MATCH(title) AGAINST ('"a railway"' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1 multiplier,
  'T' AS loc,
  id,
  title
FROM articles
WHERE MATCH(title) AGAINST ('railway' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1 multiplier,
  'T' AS loc,
  id,
  title
FROM articles
WHERE MATCH(title) AGAINST ('employee' IN BOOLEAN MODE)
UNION ALL


SELECT
  3 score,
  1 multiplier,
  'S' AS loc,
  id,
  title
FROM articles
WHERE MATCH(summary) AGAINST ('"a railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1.1 multiplier,
  'S' AS loc,
  id,
  title
FROM articles
WHERE MATCH(summary) AGAINST ('"railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1.1 multiplier,
  'S' AS loc,
  id,
  title
FROM articles
WHERE MATCH(summary) AGAINST ('"a railway"' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1.1 multiplier,
  'S' AS loc,
  id,
  title
FROM articles
WHERE MATCH(summary) AGAINST ('railway' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1.1 multiplier,
  'S' AS loc,
  id,
  title
FROM articles
WHERE MATCH(summary) AGAINST ('employee' IN BOOLEAN MODE)
UNION ALL


SELECT
  3 score,
  1.5 multiplier,
  'C' AS loc,
  id,
  title
FROM articleSections
INNER JOIN articles a ON a.id = artId
WHERE MATCH(content) AGAINST ('"a railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1.5 multiplier,
  'C' AS loc,
  id,
  title
FROM articleSections
INNER JOIN articles a ON a.id = artId
WHERE MATCH(content) AGAINST ('"railway employee"' IN BOOLEAN MODE)
UNION ALL
SELECT
  2 score,
  1.5 multiplier,
  'C' AS loc,
  id,
  title
FROM articleSections
INNER JOIN articles a ON a.id = artId
WHERE MATCH(content) AGAINST ('"a railway"' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1.5 multiplier,
  'C' AS loc,
  id,
  title
FROM articleSections
INNER JOIN articles a ON a.id = artId
WHERE MATCH(content) AGAINST ('railway' IN BOOLEAN MODE)
UNION ALL
SELECT
  1 score,
  1.5 multiplier,
  'C' AS loc,
  id,
  title
FROM articleSections
INNER JOIN articles a ON a.id = artId
WHERE MATCH(content) AGAINST ('employee' IN BOOLEAN MODE)

) t
WHERE score > 0
GROUP BY id, title
ORDER BY score DESC, title;
;
4

1 に答える 1

0

これはコメントするには長すぎます。

どうやら、自然言語モードの検索でもブール検索モードでも満たされない、非常に具体的なスコアリングのニーズがあるようです。MySQL には、検索に一致するキーワードのリストを提供し、それをスコアリングに使用できる隠しメカニズムがあるのではないかと思います。私は何も知りません。

大規模なコーパスと比較的まれな単語 (探している単語が比較的少数のドキュメントに含まれていることを意味します) がある場合は、ブール モードを使用して検索スペースを絞り込むことができます。このようなクエリは次のようになります。

select t.id, sum(terms.score * wherefactor.factor)
from (select t.*
      . . .
      where MATCH(title, summary, content) AGAINST ('railway employee' IN BOOLEAN MODE)
     ) t left outer join
     (SELECT 3 score, 'a railway employee' term UNION ALL
      SELECT 2 score, 'railway employee' term UNION ALL
      SELECT 2 score, 'a railway' term UNION ALL
      SELECT 1 score, 'employee' term UNION ALL
      SELECT 1 score, 'railway' term UNION ALL
      SELECT 0 score, 'a' term
    ) terms cross join
    (SELECT 'T' as which, 1.0 as factor UNION ALL
     SELECT 'S', 1.1 UNION ALL
     SELECT 'C', 1.5
    ) wherefactor
    on (case when wherefacctor.which = 'T' then title 
             when wherefactor.which = 'S' then subject
             when wherefactor.which = 'C' then content
        end) like concat('%', term, '%')
group by t.id;

これにより、スコアリング アルゴリズムの詳細とともに全文検索のパフォーマンスが得られるはずです。

別の可能性として、既知のレキシコンがある場合、文書用語テーブルを作成することができます。このようなテーブルには、ドキュメントごとに 1 つの行があり、ドキュメント内の重要な用語 (これは「レキシコン」と呼ばれます) があります。このようなデータ構造を使用すると、任意のスコア メカニズムを自由に実装できます。

于 2013-06-24T13:34:48.677 に答える