<?xml version="1.0" encoding="UTF-8" ?>
<entry
	xmlns="http://www.w3.org/2005/Atom"
	xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
	xml:lang="ja-JP"
>
	<title>SennaのSnippet関数を使うためのSQL文を生成したい</title>
	<id>tag:txqz.net,2006-10-17:blog/2006/10/17/2115</id>
	<link rel="self" href="http://txqz.net/blog/2006/10/17/2115.atom"/>
	<link rel="alternate" type="application/rss+xml" href="http://txqz.net/blog/2006/10/17/2115.rdf"/>
	<link rel="alternate" type="application/xhtml+xml" href="http://txqz.net/blog/2006/10/17/2115.xhtml"/>
	<link rel="alternate" type="text/html" href="http://txqz.net/blog/2006/10/17/2115.html"/>
	<link rel="contents" href="http://txqz.net/blog/2006/10/17/.atom" title="2006年10月17日"/>
	<link rel="first" href="http://txqz.net/blog/2001/08/04/0001.atom" title="地球空冷化"/>
	<link rel="prev" href="http://txqz.net/blog/2006/10/16/2241.atom" title="ナイス"/>
	<link rel="next" href="http://txqz.net/blog/2006/10/18/1201.atom" title="htt_server プロセスが暴走したとき"/>
	<link rel="last" href="http://txqz.net/blog/2008/12/19/2152.atom" title="浜松市街地を通り抜けて、ムーンライトながら～の思い出"/>
	<author>
		<name>陽坂智佐</name>
		<email>spambasket@txqz.net</email>
	</author>
	<content type="xhtml">
		<div xmlns="http://www.w3.org/1999/xhtml">
<p><a href="http://qwik.jp/senna/old_mysql_binding_docs.html#418ed1514ab16a435dfff0e09f6d0161" title="Senna 組み込み型全文検索エンジン - 旧ブラジル版MySQLバインディングのドキュメント置き場">Sennaのsnippet udf</a>を使うSQLは:</p>
<pre><code class="sql">SELECT snippet(文書, snippetの長さの最大バイト数, snippetの最大個数, 文書の文字コード, htmlエンコーディングの有無, snippetの開始タグ, snippetの終了タグ, 単語1, 単語1の前につけられるタグ, 単語1の後につけられるタグ, 単語2, 単語2の前につけられるタグ, 単語2の後につけられるタグ, ...);</code></pre>
<p>となっている。単語の数に応じて引数の数が変化するので、PreparedStatementを使えない。</p>
<p>簡単のためにフレーズ検索は考えないことにする。検索窓とかからスペース区切りの検索フレーズを受け取ったら、snippet関数の第8引数以降を何とかして生成したい。</p>
<p>against()の中はPreparedStatementを使えるので、prepareするSQL文は以下のようになるかなー (AND検索する場合):</p>
<pre><code class="sql">SELECT title, snippet(body,256,2,'utf8',1,'','',<var>あとで追加する部分</var>) AS snip FROM items WHERE MATCH(title,body) AGAINST(? in boolean mode) order by MATCH(title,body) AGAINST(? in boolean mode);</code></pre>
<p>で、空白区切りのクエリを受け取ったら:</p>
<pre><code class="php">$queries = explode(' ',$q);
$snip = "";
$against = "";
foreach($queries as $idx => $each){
    $snip .= ','.mysql_real_escape_string($each).",'&lt;span class=\"query q$idx\"&gt;','&lt;/span&gt;'";
    $against .= '+'.$each;
}
$sql = "SELECT title, snippet(body,256,2,'utf8',1,'',''$snip) AS snip FROM items WHERE MATCH(title,body) AGAINST(? in boolean mode) order by MATCH(title,body) AGAINST(? in boolean mode)";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $against, $against);</code></pre>
<p>って感じ? 定石はどんななんだろ。</p>
		</div>
	</content>
	<category term="MySQL"/>
	<category term="PHP"/>
	<category term="Senna"/>
	<category term="Snippet"/>
	<category term="検索エンジン"/>
	<trackback:ping>http://txqz.net/blog/2006/10/17/2115/tb</trackback:ping>
	<published>2007-07-28T18:53:56+09:00</published>
	<updated>2007-07-28T18:53:56+09:00</updated>
	<rights>Attribution-Noncommercial-Share Alike 3.0 Unported</rights>
</entry>