3

タグを使用して全文検索を試みていますが、正しく機能しません。添付画像をチェックしてください。ここに画像の説明を入力してください

クエリは次のとおりです。

 SELECT *, 
         MATCH(tags) AGAINST ('tag3 tag6 tag4') AS score 
    FROM items
ORDER BY score DESC

スコアが正しい順序フィールドで順序付けられていないのはなぜですか?2番目の行に検索したすべてのタグがあり、最初のフィールドにtag3キーワードがないことを確認すると、

つまり、idフィールドの順序は5,1,2 ..などであり、1,5,2..などではありません。

私の間違いはどこにありますか?

次に、最初にタグフィールドで検索したいのですが、結果がない場合は、説明フィールド内のFULLTEXTと同じキーワードを検索したいので、タグが一致しない場合、ユーザーはタグと説明の両方で検索します。同じクエリで可能ですか?または、2つの別々のクエリが必要ですか?

4

3 に答える 3

2

このドキュメントhttp://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.htmlには、「非常に小さなテーブルの場合、単語の分散はそのセマンティック値を適切に反映しておらず、このモデルは時々奇妙な結果を生む」

アイテムテーブルが小さい場合(たとえば、サンプルテーブル)、おそらくこの問題が発生し、「奇妙な」結果が得られます。

このクエリを試してIN BOOLEAN MODE、結果が予測と一致するかどうかを確認することをお勧めします。これを試して。

    SELECT *, 
           MATCH(tags) AGAINST ('tag3 tag6 tag4' IN BOOLEAN MODE) AS score 
      FROM items
  ORDER BY score DESC

ブールモードでは、単語分布のランク付けが無効になります。自然言語モードとブールモードの違いを理解する必要があることに注意してください。適切なサイズのテーブルができたら、どちらを使用するかを賢く選択してください。ブログに含まれている種類のタグを検索する場合は、ブール値が最適な方法かもしれません。

于 2012-09-10T22:23:46.513 に答える
1

まず、Windows7マシンのMySQL5.5.12にロードされたサンプルデータを次に示します。

mysql> DROP DATABASE IF EXISTS lspuk;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE DATABASE lspuk;
Query OK, 1 row affected (0.00 sec)

mysql> USE lspuk
Database changed
mysql> CREATE TABLE items
    -> (
    ->     id int not null auto_increment,
    ->     description VARCHAR(30),
    ->     tags VARCHAR(30),
    ->     primary key (id),
    ->     FULLTEXT tags_ftndx (tags)
    -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO items (description,tags) VALUES
    -> ('the first' ,'tag1 tag3 tag4'),
    -> ('the second','tag5 tag1 tag2'),
    -> ('the third' ,'tag5 tag1 tag9'),
    -> ('the fourth','tag5 tag6 tag2'),
    -> ('the fifth' ,'tag4 tag3 tag6'),
    -> ('the sixth' ,'tag2 tag3 tag6');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql>

MySQLでタグの作成がどのように行われているかを確認してください。

mysql> SELECT 'tag1',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag1%' UNION
    -> SELECT 'tag2',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag2%' UNION
    -> SELECT 'tag3',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag3%' UNION
    -> SELECT 'tag4',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag4%' UNION
    -> SELECT 'tag5',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag5%' UNION
    -> SELECT 'tag6',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag6%' UNION
    -> SELECT 'tag9',COUNT(1) tag_count FROM items WHERE tags LIKE '%tag9%';
+------+-----------+
| tag1 | tag_count |
+------+-----------+
| tag1 |         3 |
| tag2 |         3 |
| tag3 |         3 |
| tag4 |         2 |
| tag5 |         3 |
| tag6 |         3 |
| tag9 |         1 |
+------+-----------+
7 rows in set (0.00 sec)

mysql>

注意深く見て、次の事実に注意してください。

  1. 各行には正確に3つのタグがあります
  2. タグが要求される順序と、各タグがいくつ存在するかがスコアを左右するようです

tag4を削除してクエリを実行すると、スコアはまったく得られません。

mysql> SELECT *,MATCH(tags) AGAINST ('tag3 tag6') as score FROM items ORDER BY score DESC;
+----+-------------+----------------+-------+
| id | description | tags           | score |
+----+-------------+----------------+-------+
|  1 | the first   | tag1 tag3 tag4 |     0 |
|  2 | the second  | tag5 tag1 tag2 |     0 |
|  3 | the third   | tag5 tag1 tag9 |     0 |
|  4 | the fourth  | tag5 tag6 tag2 |     0 |
|  5 | the fifth   | tag4 tag3 tag6 |     0 |
|  6 | the sixth   | tag2 tag3 tag6 |     0 |
+----+-------------+----------------+-------+
6 rows in set (0.00 sec)

評価方法は、トークンフィールドの平均数に基づいているようであり、特定の順序での特定の値の有無がスコアリングに影響します。さまざまなスタイルのスコアリングとタグ指定を適用する場合は、さまざまなスコアに注意してください。

mysql> SELECT *,MATCH(tags) AGAINST ('tag3 tag6 tag4') as score FROM items ORDER BY score DESC;
+----+-------------+----------------+--------------------+
| id | description | tags           | score              |
+----+-------------+----------------+--------------------+
|  1 | the first   | tag1 tag3 tag4 | 0.6700310707092285 |
|  5 | the fifth   | tag4 tag3 tag6 | 0.6700310707092285 |
|  2 | the second  | tag5 tag1 tag2 |                  0 |
|  3 | the third   | tag5 tag1 tag9 |                  0 |
|  4 | the fourth  | tag5 tag6 tag2 |                  0 |
|  6 | the sixth   | tag2 tag3 tag6 |                  0 |
+----+-------------+----------------+--------------------+
6 rows in set (0.00 sec)

mysql> SELECT *,MATCH(tags) AGAINST ('tag3 tag6 tag4' IN BOOLEAN MODE) as score FROM items ORDER BY score DESC;
+----+-------------+----------------+-------+
| id | description | tags           | score |
+----+-------------+----------------+-------+
|  5 | the fifth   | tag4 tag3 tag6 |     3 |
|  1 | the first   | tag1 tag3 tag4 |     2 |
|  6 | the sixth   | tag2 tag3 tag6 |     2 |
|  4 | the fourth  | tag5 tag6 tag2 |     1 |
|  2 | the second  | tag5 tag1 tag2 |     0 |
|  3 | the third   | tag5 tag1 tag9 |     0 |
+----+-------------+----------------+-------+
6 rows in set (0.00 sec)

mysql> SELECT *,MATCH(tags) AGAINST ('+tag3 +tag6 +tag4' IN BOOLEAN MODE) as score FROM items ORDER BY score DESC;
+----+-------------+----------------+-------+
| id | description | tags           | score |
+----+-------------+----------------+-------+
|  5 | the fifth   | tag4 tag3 tag6 |     1 |
|  1 | the first   | tag1 tag3 tag4 |     0 |
|  2 | the second  | tag5 tag1 tag2 |     0 |
|  3 | the third   | tag5 tag1 tag9 |     0 |
|  4 | the fourth  | tag5 tag6 tag2 |     0 |
|  6 | the sixth   | tag2 tag3 tag6 |     0 |
+----+-------------+----------------+-------+
6 rows in set (0.00 sec)

mysql>

解決策は、BOOLEAN MODEスコアを評価し、次に非BOOLEANMODEスコアを次のように評価するように見えます。

SELECT *,
MATCH(tags) AGAINST ('tag3 tag6 tag4') as score1,
MATCH(tags) AGAINST ('+tag3 +tag6 +tag4' IN BOOLEAN MODE) as score2
FROM items ORDER BY score2 DESC, score1 DESC;

サンプルデータに対する結果は次のとおりです。

mysql> SELECT *,
    -> MATCH(tags) AGAINST ('tag3 tag6 tag4') as score1,
    -> MATCH(tags) AGAINST ('+tag3 +tag6 +tag4' IN BOOLEAN MODE) as score2
    -> FROM items ORDER BY score2 DESC, score1 DESC;
+----+-------------+----------------+--------------------+--------+
| id | description | tags           | score1             | score2 |
+----+-------------+----------------+--------------------+--------+
|  5 | the fifth   | tag4 tag3 tag6 | 0.6700310707092285 |      1 |
|  1 | the first   | tag1 tag3 tag4 | 0.6700310707092285 |      0 |
|  2 | the second  | tag5 tag1 tag2 |                  0 |      0 |
|  3 | the third   | tag5 tag1 tag9 |                  0 |      0 |
|  4 | the fourth  | tag5 tag6 tag2 |                  0 |      0 |
|  6 | the sixth   | tag2 tag3 tag6 |                  0 |      0 |
+----+-------------+----------------+--------------------+--------+
6 rows in set (0.00 sec)

mysql>

または、プラス記号を使用しないようにすることができます

mysql> SELECT *,
    -> MATCH(tags) AGAINST ('tag3 tag6 tag4') as score1,
    -> MATCH(tags) AGAINST ('tag3 tag6 tag4' IN BOOLEAN MODE) as score2
    -> FROM items ORDER BY score2 DESC, score1 DESC;
+----+-------------+----------------+--------------------+--------+
| id | description | tags           | score1             | score2 |
+----+-------------+----------------+--------------------+--------+
|  5 | the fifth   | tag4 tag3 tag6 | 0.6700310707092285 |      3 |
|  1 | the first   | tag1 tag3 tag4 | 0.6700310707092285 |      2 |
|  6 | the sixth   | tag2 tag3 tag6 |                  0 |      2 |
|  4 | the fourth  | tag5 tag6 tag2 |                  0 |      1 |
|  2 | the second  | tag5 tag1 tag2 |                  0 |      0 |
|  3 | the third   | tag5 tag1 tag9 |                  0 |      0 |
+----+-------------+----------------+--------------------+--------+
6 rows in set (0.00 sec)

mysql>

いずれにせよ、BOOLEANモードと非BOOLEANモードを同時に組み込む必要があります。

于 2012-09-10T22:58:06.433 に答える
0

スコアDESC、IDDESCで順序を変更します。スコア値が同じであると仮定すると、5の行が最初に表示されます。

于 2012-09-10T22:09:00.860 に答える