0

ユーザーがフィールドを 1 つしか持たない MySQL で検索を実行しようとしています。テーブルは次のようになります。

ID          BIGINT
TITLE       TEXT
DESCRIPTION TEXT
FILENAME    TEXT
TAGS        TEXT
ACTIVE      TINYINT

ここで、ユーザーが だけを入力した場合blah blubber、検索では、フィールドTITLEDESCRIOTIONFILENAMEまたはにすべての単語が表示されるかどうかを確認する必要がありますTAGS。結果自体は関連性によって並べ替える必要があるため、文字列がレコードに表示される頻度。このサンプルデータを取得しました:

ID   | TITLE   | DESCRIPTION  | FILENAME | TAGS | ACTIVE
1    | blah    | blah         | bdsai    | bdha | 1
2    | blubber | blah         | blah     | adsb | 1
3    | blah    | dsabsadsab   | dnsa     | dsa  | 1

この例では、ID 2 が一番上 (2x blah、1x blubber)、次に 1 (2x blah )、3 (1x blah) である必要があります。ユーザーがより多くの単語を入力できるように、このプロセスは動的である必要があり、関連性は 1 つまたは複数の単語と同じように機能します。

これは MySQL でのみ実現できますか、それとも PHP を使用する必要がありますか? これはどのように正確に機能しますか?

ご助力ありがとうございます!よろしく、フロリアン

編集:Tom Macの答えを試した後の結果は次のとおりです。

次のような 4 つのレコードがあります。

ID  | TITLE | DESCRIPTION | FILENAME | TAGS                          | ACTIVE
1   | s     | s           | s        | s                             | 1
2   | 0     | fdsadf      | sdfs     | a,b,c,d,e,f,s,a,a,s,s,as,sada | 1
3   | 0     | s           | s        | s                             | 1
4   | a     | a           | a        | a                             | 1

ここで、文字列 を検索するとs、上位 3 つのレコードのみが取得され、関連性が s の順に並べられます。つまり、レコードは次のように orderer にする必要があります。

ID | TITLE | DESCRIPTION | FILENAME | TAGS                          | ACTIVE
2  | 0     | fdsadf      | sdfs     | a,b,c,d,e,f,s,a,a,s,s,as,sada | 1        <== 8x s
1  | s     | s           | s        | s                             | 1        <== 4x s
3  | 0     | s           | s        | s                             | 1        <== 3x s

今、私はこのようなクエリを試しました (テーブルの名前は ですPAGES):

select t . *
  from (

        select 
              match(title) against('*s*' in boolean mode) 
            + match(description) against('*s*' in boolean mode) 
            + match(filename) against('*s*' in boolean mode) 
            + match(tags) against('*s*' in boolean mode) 
            as matchrank,
                bb . *
          from pages bb) t
 where t.matchrank > 0
 order by t.matchrank desc

このクエリは次を返します。

matchRank | ID  | TITLE | DESCRIPTION | FILENAME | TAGS                          | ACTIVE
2         | 2   | 0     | fdsadf      | sdfs     | a,b,c,d,e,f,s,a,a,s,s,as,sada | 1

これはワイルドカードのせいですか?*s*文字列も値を見つける必要があると思いますs...

4

2 に答える 2

2

これはあなたを助けるかもしれません。ただし、MySQL テーブルが MyISAM エンジンを使用していると想定しています。

create table blubberBlah (id int unsigned not null primary key auto_increment,
title varchar(50) not null,
description varchar(50) not null,
filename varchar(50) not null,
tags varchar(50)not null,
active tinyint not null
) engine=MyISAM;

insert into blubberBlah (title,description,filename,tags,active) 
values ('blah','blah','bdsai','bdha',1);
insert into blubberBlah (title,description,filename,tags,active) 
values ('blubber','blah','blah','adsb',1);
insert into blubberBlah (title,description,filename,tags,active) 
values ('blah','dsabsadsab','dnsa','dsa',1);

select t.*
from
(
 select MATCH (title) AGAINST ('blubber blah' IN BOOLEAN MODE)
       +MATCH (description) AGAINST ('blubber blah' IN BOOLEAN MODE)
       +MATCH (fileName) AGAINST ('blubber blah' IN BOOLEAN MODE)
       +MATCH (tags) AGAINST ('blubber blah' IN BOOLEAN MODE) as matchRank,
       bb.*
from blubberBlah bb
) t
order by t.matchRank desc;

編集

このソリューションが行うもう 1 つの前提は、検索対象の文字列の長さが 4 文字以上であることです。「検索」文字列、つまり「blubber」または「blah」が 1、2、または 3 文字になる可能性がある場合は、いつでも my.cnf ファイルに移動して、構成オプションのft_min_word_len=1下に追加できます。[mysqld]その後、MySQL を再起動すると、準備完了です。

最後に、このアプローチの使用を検討している場合は、各列に FULLTEXT INDEX を追加する必要があります。したがって:

ALTER TABLE blubberBlah add fulltext index `blubberBlahFtIdx1`(`title`);
ALTER TABLE blubberBlah add fulltext index `blubberBlahFtIdx2`(`description`);
ALTER TABLE blubberBlah add fulltext index `blubberBlahFtIdx3`(`filename`);
ALTER TABLE blubberBlah add fulltext index `blubberBlahFtIdx4`(`tags`);

BOOLEAN FULLTEXT 検索の詳細については、MySQL Docsを参照してください。

于 2011-10-24T11:22:35.740 に答える
1

「ブールモード」で検索するのではなく、Match() Against() を使用してスコアを決定します。これらのスコアを合計して、関連性を取得します。

于 2012-06-06T13:51:09.813 に答える