ホームページ  >  記事  >  バックエンド開発  >  シンプルな mysql 重み付け中国語全文検索の実装_PHP チュートリアル

シンプルな mysql 重み付け中国語全文検索の実装_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:24:13729ブラウズ

単純な mysql 重み付け中国語全文検索の実装 私は Web を作成していて、データベースで全文検索を実行したいと考えています。しかし、Google は、中国語の単語の分割により、MySQL は英語の全文検索のみをサポートしていることを知りました。中国語をサポートしたい場合は、さまざまなプラグインを追加するか、より複雑なメカニズムを実装する必要があり、購入した仮想ホストはサポートしていないことがわかりました。これらの複雑なこと。必要な関数は主に 2 つのフィールドでの検索という比較的単純なものであり、いくつかのフィールドを追加してさらにいくつかの選択を実行したとしても、データ量はそれほど多くないため、慎重に考えました。速度に影響を与えるため、いくつかの回避策を講じることで要件が実現されました。

ステップ 1: 単純な検索にはlocateを使用します
Locateは、部分文字列が部分文字列に含まれるかどうかを判断できます。
名前と説明の2つの列があります。
そのため、LOCATE>0を使用して、キーワードが次の文字列に含まれるかどうかを判断できます。それ。
実際には、
SELECT * FROM table WHERE LOCATE(key, 'name')>0 OR LOCATE(key, 'description);です
このようにして、2つのドメインで特定のキーを簡単に検索できます

ステップ2: 複数のキーワードを検索します
通常、検索には複数のキーワードがあるため、キーワードごとにステップ 1 のクエリを実行する必要があります。 (もちろん、これを 1 つに結合することもできますが、ここでは怠惰なので、一度に 1 つのキーワードのみをクエリします)
次に、毎回クエリされる配列をマージして、最終的なセットを取得します。

PHP コードは次のとおりです:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>function selectlocate($tarcols,$skey){<br /> </li><li>$where ="";<br /></li><li>$connector = " ";<br /></li><li>global $count;<br /></li><li>foreach($tarcols as $tarcol ){<br /></li><li>$where .= $connector;<br /></li><li>$where .= "LOCATE('$skey', $tarcol) != 0  ";<br /></li><li>if($connector == " "){<br /></li><li>$connector = " OR ";<br /></li><li>}<br /></li><li>}<br /></li><li><br /></li><li>$sql = "SELECT * FROM pets_table WHERE $where";<br /></li><li>$result = mysql_query($sql);<br /></li><li>$ret = Array();<br /></li><li>while($item = mysql_fetch_array($result, MYSQL_ASSOC)){<br /></li><li>$count ++;<br /></li><li>$ret[] = $item;<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>} </li></ol>
ステップ 3: 重みのマッチング
上記のステップ 2 の結果は、実際には順序付けされていません。通常、フィールドを検索すると:
1. このフィールドがキーワードとまったく同じである場合、一般的に、この結果は最も関連性が高いはずです
2. 1 回しか出現しない場合、関連性は最も低くなります。
3. 出現回数が他の行の出現回数よりも高い場合、その相関は 2 の結果よりも高くなります。したがって、検索時にこの順序で重みが考慮されます。それらは完全に等しいので、重みは 1000 です
b 1 回出現した場合、重みは 10、n 回出現した場合、重みは n*10 になります
重みは、各検索結果に付けられます。 》次に、同じアイテムをマージします---》そして重みを累積し、最後に重みで並べ替えて、並べ替えられた検索結果を取得します。

以下は、1つのフィールドに対応する2種類の1つのキーワードのクエリコードです(上記のコードは複数のフィールドに1つのキーワードです)クエリ(2つの配列をマージするコードを除く、関連するコードはステップ4にあります)、ただ走査します各キーワードとフィールドを使用して検索を完了できます

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>$count = 0;<br /> </li><li>function selectequal($col,$skey){<br /></li><li>$connector = " ";<br /></li><li>global $count;<br /></li><li>$sql = "SELECT * FROM pets_table WHERE LOWER($col)=LOWER('$skey')";<br /></li><li>$result = mysql_query($sql);<br /></li><li>$ret = Array();<br /></li><li>while($item = mysql_fetch_array($result, MYSQL_ASSOC)){<br /></li><li>$count ++;<br /></li><li>$item["weight"] = 1000;<br /></li><li>$ret[] = $item;<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>}<br /></li><li>function selectlocate($col,$skey){<br /></li><li>global $count;<br /></li><li>$sql = "SELECT *,(LENGTH(description) - LENGTH(REPLACE(description, '$skey', '')))/LENGTH('$skey') *10 as weight FROM pets_table WHERE LOCATE(LOWER('$skey'),LOWER($col))>0";<br /></li><li>$result = mysql_query($sql);<br /></li><li>$ret = Array();<br /></li><li>while($item = mysql_fetch_array($result, MYSQL_ASSOC)){<br /></li><li>$count ++;<br /></li><li>$ret[] = $item;<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>} </li></ol>



ステップ 4: フィールドの重み
私のニーズでは、明らかに名前フィールドが説明よりも重要であるため、一致する場合、名前フィールドの結果は次のようになります。傾斜しているため、フィールドに重み係数を追加できます。

1. 名前フィールドが一致する場合は、係数を 10 に設定します。

ステップ 3 で毎回計算される重みを乗算します。この係数を使用すると、より効果的な新しい重み値を取得できます。
最後に、重みで並べ替えて、最も関連性の高い検索結果を取得します

その他の詳細:
キーワードが等価条件を満たしている場合でも、検索条件を使用しても結果が返されるため、検索条件を使用するときは、平等な状況

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li><?php<br /> </li><li>$count = 0;<br /></li><li>function selectequal($col,$val,$skey){<br /></li><li>$connector = " ";<br /></li><li>global $count;<br /></li><li>$sql = "SELECT * FROM pets_table WHERE LOWER($col)=LOWER('$skey')";<br /></li><li>$result = mysql_query($sql);<br /></li><li>$ret = Array();<br /></li><li>while($item = mysql_fetch_array($result, MYSQL_ASSOC)){<br /></li><li>$count ++;<br /></li><li>$item["weight"] = 1000*$val;<br /></li><li>$ret[] = $item;<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>}<br /></li><li>function selectlocate($col,$val,$skey){<br /></li><li>global $count;<br /></li><li>$sql = "SELECT *,(LENGTH(description) - LENGTH(REPLACE(description, '$skey', '')))/LENGTH('$skey') *10*$val as weight FROM pets_table WHERE LOCATE(LOWER('$skey'),LOWER($col))>0 AND LOWER($col)!=LOWER('$skey')";<br /></li><li>$result = mysql_query($sql);<br /></li><li>$ret = Array();<br /></li><li>while($item = mysql_fetch_array($result, MYSQL_ASSOC)){<br /></li><li>$count ++;<br /></li><li>$ret[] = $item;<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>}<br /></li><li>function cleanarr($arr){<br /></li><li>global $count;<br /></li><li>$tmp = Array();<br /></li><li>$tmpall = Array();<br /></li><li>foreach($arr as $item){<br /></li><li>if(array_key_exists($item['uid'], $tmp)){<br /></li><li>$tmp[$item['uid']]+=$item["weight"];<br /></li><li>}<br /></li><li>else{<br /></li><li>$tmp[$item['uid']] = $item["weight"];<br /></li><li>$tmpall[$item['uid']] = $item;<br /></li><li>}<br /></li><li>}<br /></li><li><br /></li><li>//sort by weight in descending order <br /></li><li>arsort($tmp);<br /></li><li><br /></li><li>$ret = Array();<br /></li><li><br /></li><li>//rebuildthe return arary<br /></li><li>$count = 0;<br /></li><li>foreach($tmp as $k=>$v){<br /></li><li>$count++;<br /></li><li>$tmpall[$k]['weight']=$v;<br /></li><li>$ret[]=$tmpall[$k];<br /></li><li>}<br /></li><li>return $ret;<br /></li><li>}<br /></li><li><br /></li><li>require_once("consvr.php");<br /></li><li><br /></li><li><br /></li><li>$colshash = array("name"=>10,"description"=>1);<br /></li><li>$ret = Array();<br /></li><li>$keywords=explode(" ", $keywords);<br /></li><li>$cols = array_keys($colshash);<br /></li><li>foreach($keywords as $keyword){<br /></li><li>foreach($colshash as $col=>$val){<br /></li><li>$ret = array_merge($ret,selectequal($col,$val, $keyword));<br /></li><li>$ret = array_merge($ret,selectlocate($col,$val, $keyword));<br /></li><li>}<br /></li><li><br /></li><li>}<br /></li><li>$ret = cleanarr($ret);<br /></li><li>$ret = array('msg' => "Success", 'count'=>$count,'children' => $ret, 'query'=>"COMPLEX:NOT READABLE");<br /></li><li>echo json_encode($ret);<br /></li><li>mysql_close();<br /></li><li><br /></li><li>?> </li></ol>















http://www.bkjia.com/PHPjc/827622.html

www.bkjia.com

tru​​ehttp://www.bkjia.com/PHPjc/827622.html技術記事シンプルな mysql 重み付け中国語全文検索を実装する Web を作成しており、データベースで全文検索を実行したいと考えています。しかし、Google は、中国語の単語の分割により、mysql は... のみをサポートしていることを知りました。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。