Nucleus(JP)フォーラム

NucleusCMS日本語版ユーザーのためのサポートフォーラムです。疑問が生じたらまずは記事検索をご利用ください。

ログインしていません。

#1 2006-01-04 20:53:07

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

今のNucleusの検索機能はコメントが検索できないなど,いろいろ制限があり,しかも拡張できない仕様になっています。
これを打破しようと,プラグインで拡張できるようにする方法を考えました。

ただ,いきなりコアの修正として提案するのも危険なので,まずはsearchresultsを置き換え可能(制限ありますが)な
プラグインとして公開し,テストして大丈夫そうであったら,あらためて本家に提案していこうかと考えています。

なお,これは佐藤(な)さんの http://wa.otesei.com/item/307 の議論を踏まえたものです。

まずは検索本体。NP_ExtensibleSearchとしています。searchresultsを置き換えできますが,nextlink,prevlinkは
プラグイン拡張に対応していません。内容的にはBLOGクラスのgetSqlQuery関数を書き換えています。

<?php
// plugin needs to work on Nucleus versions <=2.0 as well
if (!function_exists('sql_table')){
	function sql_table($name) {
		return 'nucleus_' . $name;
	}
}

class NP_ExtensibleSearch extends NucleusPlugin {

	function getName() { return 'Extensible Search'; }
	function getAuthor()  { return 'Andy'; }
	function getURL() { return 'http://www.matsubarafamily.com/lab/'; }
	function getVersion() { return '0.1'; }
	
	function getDescription() { 
		return 'Plugin Extensible Search. It can replace searchresults';
	}

	function supportsFeature($what) {
		switch($what){
			case 'SqlTablePrefix':
				return 1;
			default:
				return 0;
		}
	}


	function getSqlQuery($query, $amountMonths = 0, &$highlight, $mode = '')
	{
		global $blog, $manager;
		
        $searchclass =& new SEARCH($query);
        
        $highlight	  = $searchclass->inclusive;
        
        // if querystring is empty, return empty string
        if ($searchclass->inclusive == '') 
        	return '';
            
           
		$where  = $searchclass->boolean_sql_where('ititle,ibody,imore');
		$select = $searchclass->boolean_sql_select('ititle,ibody,imore');

		// get list of blogs to search
		$blogs 		= $searchclass->blogs; 		// array containing blogs that always need to be included
		$blogs[]	= $blog->getID();			// also search current blog (duh)
		$blogs 		= array_unique($blogs);		// remove duplicates
		$selectblogs = '';
		if (count($blogs) > 0)
			$selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';

		if ($mode == '') 
		{
//			$query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
			$sqlquery = 'SELECT i.inumber as itemid ';
			if ($select) 
				$sqlquery .= ', '.$select. ' as score ';
		} else {
			$sqlquery = 'SELECT COUNT(*) as result ';
		}
			
		$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
			   . ' WHERE i.iauthor=m.mnumber'
			   . ' and i.icat=c.catid'
			   . ' and i.idraft=0'	// exclude drafts
			   . $selectblogs
					// don't show future items
			   . ' and i.itime<=' . mysqldate($blog->getCorrectTime())
			   . ' and '.$where;

		// take into account amount of months to search
		if ($amountMonths > 0) 
		{
			$localtime = getdate($blog->getCorrectTime());
			$timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
			$sqlquery .= ' and i.itime>' . mysqldate($timestamp_start);
		}
		
		$items = $this->getArray($sqlquery);
		
		$manager->notify('PreSearchResults',array('blogs' => &$blogs, 'items' => &$items, 'query' => $query));


		if (!$items) return '';

		if ($mode == '')
		{
			$sqlquery = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed ';
			if ($select) 
				$sqlquery .= ', '.$select. ' as score ';
			$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
			   . ' WHERE i.iauthor=m.mnumber'
			   . ' and i.icat=c.catid';
			$sqlquery .= ' and i.inumber in (' . implode(',', $items) . ')';
			if ($select) 
				$sqlquery .= ' ORDER BY score DESC';
			else 
				$sqlquery .= ' ORDER BY i.itime DESC ';
		}

		return $sqlquery;		
	}
	
	function getArray($query) {
		$res = sql_query($query);
		$array = array();
		while ($itemid = mysql_fetch_row($res)) {
			array_push($array, $itemid[0]);
		}
		return $array;
	}
	

	function search($query, $template, $amountMonths, $maxresults, $startpos) {
		global $CONF, $manager, $blog;

		$highlight 	= '';
		$sqlquery	= $this->getSqlQuery($query, $amountMonths, $highlight);
		
		if (!$sqlquery)
		{
			// no query -> show everything
            $extraquery = '';
		    $amountfound = $blog->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
		} else {
			
			// add LIMIT to query (to split search results into pages)
            if (intval($maxresults > 0)) 
	            $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);

			// show results
		    $amountfound = $blog->showUsingQuery($template, $sqlquery, $highlight, 1, 1);

			// when no results were found, show a message 
    		if ($amountfound == 0) 
    		{
	    		$template =& $manager->getTemplate($template);
    			$vars = array(
    				'query'		=> htmlspecialchars($query),
    				'blogid'	=> $this->getID()
    			);
	    		echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
    		}
        }
        
		return $amountfound;
	}


	function doSkinVar($skinType, $template, $maxresults=50) {
		global $blog, $query, $amount, $startpos, $manager;

		$manager->notify('PreBlogContent',array('blog' => &$blog, 'type' => 'searchresults'));
		
		$this->amountfound = $this->search($query, $template, $amount, $maxresults, $startpos);
		$manager->notify('PostBlogContent',array('blog' => &$blog, 'type' => 'searchresults'));

	}

}
?>

検索機能を拡張するプラグインはPreSearchResultsというイベントに登録します。
渡されるパラメータは$data['query']が検索語,$data['blogs']が検索対象となるブログIDの配列,$data['items']が検索結果となるアイテムIDの配列への参照です。ここにプラグインが見つけたアイテムIDを重複がないように加えることで検索結果に付け加えられます。
サンプルとしてコメントやトラックバックを検索するプラグインを試作しました。

<?php
// plugin needs to work on Nucleus versions <=2.0 as well
if (!function_exists('sql_table')){
	function sql_table($name) {
		return 'nucleus_' . $name;
	}
}

class NP_CommentSearch extends NucleusPlugin {

	function getName() { return 'Comment Search'; }
	function getAuthor()  { return 'Andy'; }
	function getURL() { return 'http://www.matsubarafamily.com/lab/'; }
	function getVersion() { return '0.1'; }
	
	function getDescription() { 
		return 'Comment Search plugin. works with Extensible Search';
	}

	function supportsFeature($what) {
		switch($what){
			case 'SqlTablePrefix':
				return 1;
			default:
				return 0;
		}
	}


	function getEventList() {
		return array('PreSearchResults'); 
	}



	function event_PreSearchResults(&$data) {
		global $blog, $manager;
		$blogs = $data['blogs'];
		$query = $data['query'];
		$items = & $data['items'];
		$searchclass =& new SEARCH($query);

		$sqlquery = 'SELECT i.inumber as itemid '
					.'FROM '.sql_table('item').' as i left join '.sql_table('comment').' as cm on i.inumber = cm.citem ';
		if ($manager->pluginInstalled('NP_TrackBack')) {
			$sqlquery .= 'left join '.sql_table('plugin_tb').' as t on i.inumber = t.tb_id ';
			$where  = $searchclass->boolean_sql_where('xxx.cm.cbody,xxx.t.title,xxx.t.excerpt');
		} else {
			$where  = $searchclass->boolean_sql_where('xxx.cm.cbody');
		}
		$where = strtr($where, array('i.xxx.'=> ''));
		$sqlquery .= ' WHERE i.idraft = 0 and i.itime <= '.mysqldate($blog -> getCorrectTime())
					.' and i.iblog in (' . implode(',', $blogs) . ') '
					.' and '.$where;
		$res = sql_query($sqlquery);
		$array = array();
		while ($itemid = mysql_fetch_row($res)) {
			array_push($array, $itemid[0]);
		}
		$data['items'] = array_unique(array_merge($items,$array));
	}

}
?>

ご意見をお願いします。

オフライン

#2 2006-01-06 01:35:57

kazy
メンバー
From: 神戸
登録日: 2006-01-04
投稿: 5

Re: 検索機能をプラグインで拡張可能に

最近Nucleusを使い初めた若造ですが、使ってみました。ちゃんと動いているようです。
丁度blogを横断してカテゴリを検索したかったので、カテゴリ検索のpluginを
コメント検索のサンプルコードを参考にして適当に作ってみました。(PHPは初めて触ったので半分勘で作ってます)

載せるまでもないようなソースですが、一応PreSearchResultsだけ載せておきます。
絞り込み検索等の細かい動きがなんか変ですが、原因不明です。

   function event_PreSearchResults(&$data) {
      global $blog, $manager;
      $blogs = $data['blogs'];
      $query = $data['query'];
      $items = & $data['items'];
      $searchclass =& new SEARCH($query);

      $sqlquery = 'SELECT i.inumber as itemid '
        .'FROM '.sql_table('item').' as i left join '.sql_table('category').' as ct on i.icat = ct.catid ';

      if ($manager->pluginInstalled('NP_MultipleCategories')) {
         //$sqlquery .= 'left join '.sql_table('plug_multiple_categories').' as mc on i.inumber = mc.item_id ';

         $where  = $searchclass->boolean_sql_where('xxx.ct.cname');
         
      } else {
         $where  = $searchclass->boolean_sql_where('xxx.ct.cname');
      }
     
      $where = strtr($where, array('i.xxx.'=> ''));
      $sqlquery .= ' WHERE i.idraft = 0 and i.itime <= '.mysqldate($blog -> getCorrectTime())
               .' and i.iblog in (' . implode(',', $blogs) . ') '
               .' and '.$where;
      $res = sql_query($sqlquery);
      $array = array();
      while ($itemid = mysql_fetch_row($res)) {
         array_push($array, $itemid[0]);
      }
      $data['items'] = array_unique(array_merge($items,$array));
   }

SEARCH.php等を弄ればなんとかなるそうですが、バージョンアップ等を考えるとpluginで実現したかったので、こういう枠組みだけでもあるのは有難いです。

あと、勿論(?)MulipleCategoriesは未対応です。
ちょっとやってみましたが無理でした…。
categories等がコロン区切りなのがネックですね。
あとは一旦idだけ抽出して変数化して、もう一回クエリを送るとかしか思い付きません…(しかもやり方がわからない)。


一つ質問なのですが、今の状態だと何も見付からなかった場合に
現在のblogの記事を全て表示してしまっていますが、この動作の意図するところは何なのでしょうか?
普通は何も表示しないと思うのですが…。

オフライン

#3 2006-01-06 02:18:09

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

kazyさん,試していただきありがとうございます。

kazy さんの発言:

一つ質問なのですが、今の状態だと何も見付からなかった場合に
現在のblogの記事を全て表示してしまっていますが、この動作の意図するところは何なのでしょうか?
普通は何も表示しないと思うのですが…。

Nucleusの標準の検索機能の動作にならっています。

オフライン

#4 2006-01-06 02:36:09

kazy
メンバー
From: 神戸
登録日: 2006-01-04
投稿: 5

Re: 検索機能をプラグインで拡張可能に

え、そうですか?Nucleus 3.21 EUC版を使用していますが、
default skinでも結果が無いときは

No search results found for ~

と出るのですが。そのあたり、何か影響のある設定などはありますか?

オフライン

#5 2006-01-06 13:29:42

kazy
メンバー
From: 神戸
登録日: 2006-01-04
投稿: 5

Re: 検索機能をプラグインで拡張可能に

うーん。昨日(?)書いた方法で、MultipleCategories対応になったような気がします。
クエリを3回も飛ばしてますが…。
変なところがあったら指摘お願いします。むしろガンガン修正して下さい。

例によって変更部分のみ上げておきます。

  function getCategoryIDs(&$searchclass) {
    $sqlquery = 'SELECT i.catid as catid '
      .'FROM '.sql_table('category').' as i WHERE '
        .$searchclass->boolean_sql_where('cname');
    $res = sql_query($sqlquery);
    $exp = '';
    while ($catid = mysql_fetch_row($res)) {
      $exp .= $catid[0] . '|';
    }
    $exp .= '99999999999999999';
    return $exp;
  }
  
  function getSubCategoryIDs(&$searchclass) {
    $sqlquery = 'SELECT i.scatid as scatid '
      .'FROM '.sql_table('plug_multiple_categories_sub').' as i WHERE '
        .$searchclass->boolean_sql_where('sname');
    $res = sql_query($sqlquery);
    $exp = '';
    while ($catid = mysql_fetch_row($res)) {
      $exp .= $catid[0] . '|';
    }
    $exp .= '99999999999999999';
    return $exp;
  }
  
   function event_PreSearchResults(&$data) {
      global $blog, $manager;
      $blogs = $data['blogs'];
      $query = $data['query'];
      $items = & $data['items'];
      $searchclass =& new SEARCH($query);

      $sqlquery = 'SELECT i.inumber as itemid '
        .'FROM '.sql_table('item').' as i left join '.sql_table('category').' as ct on i.icat = ct.catid ';

      $where  = $searchclass->boolean_sql_where('xxx.ct.cname');
      if ($manager->pluginInstalled('NP_MultipleCategories')) {
         $sqlquery .= 'left join '.sql_table('plug_multiple_categories').' as mc on i.inumber = mc.item_id ';

         $where  .= ' or mc.categories REGEXP "((^|,)('.$this->getCategoryIDs(&$searchclass).')(,|$))" '
           .' or mc.subcategories REGEXP "((^|,)('.$this->getSubCategoryIDs(&$searchclass).')(,|$))" ';
      }
     
      $where = strtr($where, array('i.xxx.'=> ''));
      $sqlquery .= ' WHERE i.idraft = 0 and i.itime <= '.mysqldate($blog -> getCorrectTime())
               .' and i.iblog in (' . implode(',', $blogs) . ') '
               .' and '.$where;
      $res = sql_query($sqlquery);
      $array = array();
      while ($itemid = mysql_fetch_row($res)) {
         array_push($array, $itemid[0]);
      }
      $data['items'] = array_unique(array_merge($items,$array));
   }

あー、なんかand検索時の動作は変えるようにしたほうが良いですかね…。
複数のカテゴリを持つような記事を検索したいときがあるような気がします。

オフライン

#6 2006-01-06 14:21:16

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

getSqlSearch関数を以下のように修正しました。

	function getSqlQuery($query, $amountMonths = 0, &$highlight, $mode = '')
	{
		global $blog, $manager;
		
        $searchclass =& new SEARCH($query);
        
        $highlight	  = $searchclass->inclusive;
        
        // if querystring is empty, return empty string
        if ($searchclass->inclusive == '') 
        	return '';
            
           
		$where  = $searchclass->boolean_sql_where('ititle,ibody,imore');
		$select = $searchclass->boolean_sql_select('ititle,ibody,imore');

		// get list of blogs to search
		$blogs 		= $searchclass->blogs; 		// array containing blogs that always need to be included
		$blogs[]	= $blog->getID();			// also search current blog (duh)
		$blogs 		= array_unique($blogs);		// remove duplicates
		$selectblogs = '';
		if (count($blogs) > 0)
			$selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';

		$sqlquery = 'SELECT i.inumber as itemid ';
		if ($select) {
			$sqlquery .= ', '.$select. ' as score ';
		}
	
		$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
			   . ' WHERE i.iauthor=m.mnumber'
			   . ' and i.icat=c.catid'
			   . ' and i.idraft=0'	// exclude drafts
			   . $selectblogs
					// don't show future items
			   . ' and i.itime<=' . mysqldate($blog->getCorrectTime())
			   . ' and '.$where;

		// take into account amount of months to search
		if ($amountMonths > 0) 
		{
			$localtime = getdate($blog->getCorrectTime());
			$timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
			$sqlquery .= ' and i.itime>' . mysqldate($timestamp_start);
		}
		
		$items = $this->getArray($sqlquery);
		
		$manager->notify('PreSearchResults',array('blogs' => &$blogs, 'items' => &$items, 'query' => $query));

		if ($mode == '')
		{
			$sqlquery = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
			$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
			   . ' WHERE i.iauthor=m.mnumber'
			   . ' and i.icat=c.catid';
			if ($items) {
				$sqlquery .= ' and i.inumber in (' . implode(',', $items) . ')';
			} else {
				$sqlquery .= ' and 1=2 ';
			}
			if ($select) 
				$sqlquery .= ' ORDER BY score DESC';
			else 
				$sqlquery .= ' ORDER BY i.itime DESC ';
		} else {
			$sqlquery = 'SELECT COUNT(*) FROM '.sql_table('item').' as i WHERE ';
			if ($items) {
				$sqlquery .= ' and i.inumber in (' . implode(',', $items) . ')';
			} else {
				$sqlquery .= ' and 1=2 ';
			}
		}

		return $sqlquery;		
	}

オフライン

#7 2006-01-06 20:20:36

kazy
メンバー
From: 神戸
登録日: 2006-01-04
投稿: 5

Re: 検索機能をプラグインで拡張可能に

普通はSQL文が生成されないことはなかった、というわけでしょうか。
無事、見付からなかった場合は何も表示されなくなりました。対応ありがとうございます。

カテゴリ検索プラグインについてですが、
SEARCH.phpの内容をパクって無理矢理ですが、AND検索等、通常期待する(と思われる)動作になりました。
一応動くようですが、何回もDBにクエリ送りまくってます。もうちょっと良いやりかた、無いでしょうか…。
多少チェックはしましたが、変な動きがあったら指摘お願いします。

いい加減長いので、添付ファイルにしておきます。


Attachments:
zip NP_CategorySearch.zip, Size: 1.4 KiB, Downloads: 424

オフライン

#8 2006-01-07 14:08:42

kazy
メンバー
From: 神戸
登録日: 2006-01-04
投稿: 5

Re: 検索機能をプラグインで拡張可能に

自分で検索クエリを解析して思ったのですが、
今の状態だと、本文とプラグインで拡張された対象との間で、正常なAND検索等ができませんよね?
例えば2つの語句でAND検索したとき、
一つが本文に、もう一つがカテゴリに含まれていた場合はヒットしません。
追加プラグイン側で対応ができなくもないですが、
それよりはExtensibleSearch側でまとめる方が良いのではないかと思います。

具体的には
[list=]
[*]クエリをExtensibleSearch側で解析[/*]
[*]下位プラグインを列挙[/*]
[*]一つ一つの語句を下位プラグインに投げる[/*]
[*]帰ってきた値を元にWHERE文を組み立てる[/*][/list]
という流れです。今回カテゴリ検索プラグインで実装したアルゴリズムに近いです。
これをすれば、各プラグイン側では一語に関する動作を記述するだけで良くなって、
非常に拡張しやすくなると思うのですが、どうでしょうか?
相変らず効率無視の上、自分で実装していませんが…。

あ、帰ってくる値というのは、itemidの列です。

オフライン

#9 2006-01-08 00:41:03

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

なるほど。確かにそれはそうですね。検討してみます。

オフライン

#10 2006-01-11 15:33:34

cha_cya
メンバー
From: 東京
登録日: 2004-08-25
投稿: 745

Re: 検索機能をプラグインで拡張可能に

すごく無責任な発言ですが、mediaディレクトリの中のテキストやPDFなんかも検索できるようになると最高ですね(もちろん記事からリンクさせてるやつで・・)
そこまでいかないと、Googleからドメイン指定で検索した方が確実になってしまいますし。
#インデックスされてさえいれば、検索できるので。インデックスされていることが前提 :?

今はできませんよね?(Nucleusの検索機能は使っていないので確認できず・・3.0くらいのときは出来なかったような)

オフライン

#11 2006-01-11 20:10:25

藤咲
Administrator
From: 広島
登録日: 2003-11-17
投稿: 1,210
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

あおった当人がまったく試せておらずもうしわけないです :oops:

cha_cya さんの発言:

今はできませんよね?(Nucleusの検索機能は使っていないので確認できず・・3.0くらいのときは出来なかったような)

難しいですね…。Nucleusの検索はあくまでMysqlのクエリーでDB内を検索していますので、DBにないものは検索できません。
それをするためにはmediaディレクトリの中身を一度DBへ取り込まないといけませんが、

・どのタイミングでそれをするのか。
・PHPからPDFの中身って取り出せるのか。
・DBの肥大化が起きないか。

通常のBlogとして使う分にはあまりPDFとかテキストファイルはアップしませんので、Blogツールとしてみるのであれば、
標準としてその機能をいれるかどうかというのはちょっと難しいかも。

イントラでNucleusを使用している私としてはあったらとても便利ですけどね wink
#現在はファイル検索にはNamazuを併用しています。


藤咲
備忘録とかもろもろ
http://fjsk.tk/

オフライン

#12 2006-01-11 20:20:50

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

この検索拡張の仕組みを使えば,記事からリンクされているPDFの内容をインデキシングして検索できるようにすることは可能だと思います。PHPだけでどこまでできるか不明ですが。

ちょっと調べたところPDFを作るライブラリはありますが,解析するライブラリってなさそうですねえ。

オフライン

#13 2006-01-11 23:42:42

nakahara21
メンバー
From: 尼崎
登録日: 2003-11-14
投稿: 1,298
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

Andy さんの発言:

ちょっと調べたところPDFを作るライブラリはありますが,解析するライブラリってなさそうですねえ。

ないですよ、ええ、ないです。あったら是非教えて欲しい。
車買う位のお金を出せば構築できると思いますけど。(←大袈裟すぎ)

所詮、pdfだってテキストファイルなんだから(←極論すぎ)テキスト情報の取り出しなんて簡単な気がするんですがねぇ。


nakahara21
http://nakahara21.com/
(ただいま調整中です)

オフライン

#14 2006-01-12 07:51:13

kimitake
メンバー
From: かるふぉるにあ
登録日: 2004-12-10
投稿: 266
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

nakahara21 さんの発言:

所詮、pdfだってテキストファイルなんだから(←極論すぎ)テキスト情報の取り出しなんて簡単な気がするんですがねぇ。

ghostscript に pdf からテキストにするツールがあるようですが、手元のやつだとイマイチな結果でした...

オフライン

#15 2006-01-12 08:08:52

kimitake
メンバー
From: かるふぉるにあ
登録日: 2004-12-10
投稿: 266
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

kimitake さんの発言:

ghostscript に pdf からテキストにするツールがあるようですが、手元のやつだとイマイチな結果でした...

xpdf にある pdftotext は少なくとも英文 pdf のテキスト化に関しては、かなり上出来です。
ちゃんとセットアップすれば日本語も問題ないと思いますが未確認。

オフライン

#16 2006-01-12 08:17:48

kimitake
メンバー
From: かるふぉるにあ
登録日: 2004-12-10
投稿: 266
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

kimitake さんの発言:

ちゃんとセットアップすれば日本語も問題ないと思いますが未確認。

連投すみません。上記ですが、ちゃんとも何も普通にセットアップした状態で変換できました。
最初テストで使った手元のファイルが腐ってたのかも(gs で出力した pdf だし 8) )

オフライン

#17 2006-01-12 10:37:58

cha_cya
メンバー
From: 東京
登録日: 2004-08-25
投稿: 745

Re: 検索機能をプラグインで拡張可能に

そうですよねー
なかなか難しいだろうなぁと思いながら別のプログラム(名称失念)でごまかしています

藤咲 さんの発言:

イントラでNucleusを使用している私としてはあったらとても便利ですけどね wink
#現在はファイル検索にはNamazuを併用しています。

ワードで作った文書とか、HTMLで再整形するのも面倒なのでよくPDFにしちゃいます
ある程度のボリュームになるとどうしてもHTMLより見やすい&再利用がしやすいので・・
日記スタイルだと使わないですよねー sad

一応不可能ではなさそうなのかな・・ smile

オフライン

#18 2006-01-12 10:42:08

nakahara21
メンバー
From: 尼崎
登録日: 2003-11-14
投稿: 1,298
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

Namazuではpdftotext使ってpdfのテキスト解析させてるんですよね。
他にもCOMとかDLLならあるんですけどねー。
うーーん。普通にphpだけでテキスト取り出しできないモノなんでしょーか。


nakahara21
http://nakahara21.com/
(ただいま調整中です)

オフライン

#19 2006-04-14 11:28:01

佐藤(な)
メンバー
From: 愛知の知多半島の田舎
登録日: 2005-09-12
投稿: 266
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

この検索拡張プラグイン対応のプラグインを作ってみて、「感動!」しました。(このトピックの最初に挙げていただいてるページのやつです。)
とっても簡単に検索項目が拡張できます。すごいです!
って、このトピックへの書き込みが遅くなりました。^^;;;
Andyさん、便利なプラグインをありがとうございます。 big_smile

「NP_ExtensibleSearchのダウンロードができた方が便利かな」&「PreSearchResultsイベント対応プラグインが増えると良いな」と思いまして、勝手にファイルをアップしてしまったのですが、大丈夫でしょうか?
途中、getSqlQuery関数を修正されているので、勝手にver0.11としました。

まだ、一般公開段階ではないのでしょうか?
wikiにも追加してしまったのですが、問題点がありましたらすみません。。。
【追記】
wikiの、NP_ExtensibleSearch解説ページは、、、
http://japan.nucleuscms.org/wiki/plugin … iblesearch
です。
この、NP_ExtensibleSearchと、対応プラグイン(※1)があれば、ユーザはプラグインやコアの改造をしないで、簡単に検索項目を拡張することができます。便利。

※1・・・コメントを検索項目に追加したい場合に、(Andyさんがサンプルとして作成された)NP_CommentSearchを使用します。
【/追記】


Attachments:
zip NP_ExtensibleSearch_v011.zip, Size: 1.95 KiB, Downloads: 669

各種プラグインを紹介するblog(鯖更新忘れ死亡中)
スキン・テンプレ変数を紹介するブログ(復活)
http://reference.nucleus.satona.net/
wa - Nucleusやウェブネタなど
http://wa.otesei.com/

オフライン

#20 2006-04-14 19:13:29

Andy
メンバー
登録日: 2004-03-18
投稿: 1,495
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

佐藤(な)さん,ありがとうございます。
kazyさんの書いた

自分で検索クエリを解析して思ったのですが、
今の状態だと、本文とプラグインで拡張された対象との間で、正常なAND検索等ができませんよね?
例えば2つの語句でAND検索したとき、
一つが本文に、もう一つがカテゴリに含まれていた場合はヒットしません。
追加プラグイン側で対応ができなくもないですが、
それよりはExtensibleSearch側でまとめる方が良いのではないかと思います。

とかにどう対応しようかなあと思いながら放置状態になっていました。
あと,プラグインとして配布するにはページスイッチも付けたいなあとか。
実はそのためにNP_Pagerの拡張を始めたところです。
志はあるのだけど作業が進まない今日この頃です。 :?

オフライン

#21 2008-12-18 23:48:54

佐藤(な)
メンバー
From: 愛知の知多半島の田舎
登録日: 2005-09-12
投稿: 266
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

検索結果から特定のアイテムを除外するというトピックが面白いなと思いまして、勝手にNP_ExtensibleSearchを改造してしまいました。

$manager->notify('PreSearchResults',array('blogs' => &$blogs, 'items' => &$items, 'query' => $query));

PreSearchResultsイベント発生部分を、↓以下のようにしただけですので、邪魔にはならないと思います。

$exclusionitems = array();
$manager->notify('PreSearchResults',array('blogs' => &$blogs, 'items' => &$items, 'query' => $query, 'exclusionitems' => &$exclusionitems));
if (count($exclusionitems))
{
	$exclusionitems = array_unique($exclusionitems);
	$items          = array_diff($items, $exclusionitems);
	$items          = array_map('intval', $items);
}

対応プラグインから、除外アイテムのリストを受け取り除外します。
UIを外部に追い出していますので、対応プラグインの作りこみ次第で柔軟に操作できます。(除外カテゴリ指定など)


Attachments:
zip NP_ExtensibleSearch.0.12.zip, Size: 1.94 KiB, Downloads: 436

各種プラグインを紹介するblog(鯖更新忘れ死亡中)
スキン・テンプレ変数を紹介するブログ(復活)
http://reference.nucleus.satona.net/
wa - Nucleusやウェブネタなど
http://wa.otesei.com/

オフライン

#22 2009-11-13 07:57:49

shinshinshin
メンバー
登録日: 2008-03-23
投稿: 7

Re: 検索機能をプラグインで拡張可能に

便利に使用させて頂いております。
extensiblesearchの検索結果に、表示させる記事数制御とページスイッチをつける方法ってないのでしょうか?!
showblogsのようにできればと思っておりますが、いかがなものでしょうか。

オフライン

#23 2011-01-06 11:41:56

PUSHMAN
メンバー
登録日: 2004-08-15
投稿: 60
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

お世話になっております。

コアを3.51にバージョンアップしたところ、
下記のようなエラーが発生しました。

mySQL error with query SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed FROM nucleus_item as i, nucleus_member as m, nucleus_category as c WHERE i.iauthor=m.mnumber and i.icat=c.catid and i.inumber in (1,2) and i.iblog in (1) ORDER BY score DESC: Unknown column 'score' in 'order clause'

90行目あたりの

if ($select)
   $sqlquery .= ' ORDER BY score DESC';
else
   $sqlquery .= ' ORDER BY i.itime DESC ';

if ($select)
   $sqlquery .= ' ORDER BY i.itime DESC ';
else
   $sqlquery .= ' ORDER BY i.itime DESC ';

とすることでとりあえずエラーは発生しなくなり、検索結果にも問題なように見えております…

が、

$sqlquery .= ' ORDER BY score DESC';

の「score」の意味がよくわからないので、少し不安ですが、とりあえずご報告まで。


マーカーのドラッグ&ドロップでGoogle Mapsの緯度経度を測定|Geocoder
http://geocoder.heartfield-web.com/

What's so bad about feeling good?
http://blog.heartfield-web.com/

オフライン

#24 2011-01-06 12:28:34

Mocchi
メンバー
登録日: 2006-11-19
投稿: 438

Re: 検索機能をプラグインで拡張可能に

ざっと見てみましたが、scoreというのは、検索のランクを表す指標ですね。検索対象の文字列との関連性の強弱を表す指標なのでしょう。どこをどうすれば直るというアドバイスは今は無理ですが、ソースが読める人はNP_ExtensibleSearch::getSqlQueryを改良してみて下さい。

今後、このようなトラブルが増えると考えています。Nucleus CMSコア部分は変化していきますが、プラグインはリリースはされているものの、メンテナンスもされずに放置されていたりといったものが複数あるかと思います。もうメンテナンスされなくなったプラグインと、メンテナンスが引き続き行われているプラグインをちゃんと分類していく必要を感じています。

あまりシビアに行うと、プラグインによる拡張性の高さという、Nucleus CMSの強みが失われてしまいますが、でも、不具合の温床となるかもしれないプラグインを野放しにしておくのも、WWWネットワーク全体としてみると、あまりするべきではないことなのかなぁと思えたりします。脆弱性を放置しておくわけですから。

おまけにこの作業をするには、チームのコアメンバー(4名)だけでは圧倒的に手数が足りないという実情もあります。。。

オフライン

#25 2011-01-06 14:50:10

PUSHMAN
メンバー
登録日: 2004-08-15
投稿: 60
ウェブサイト

Re: 検索機能をプラグインで拡張可能に

Mocciさん

解説ありがとうございます。

74行目あたりからの

if ($mode == '')
{
	$sqlquery = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
	$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
		. ' WHERE i.iauthor=m.mnumber'
		. ' and i.icat=c.catid';
	$sqlquery .= $items ? ' and i.inumber in (' . implode(',', $items) . ')' : ' and 1=2 ';
	$sqlquery .= $select ? ' ORDER BY score DESC' : ' ORDER BY i.itime DESC ';
}

	if ($select) {
		$sqlquery .= ', '.$select. ' as score ';
	}

を足して下記のように修正してみました。

if ($mode == '')
{
	$sqlquery = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
	if ($select) {
		$sqlquery .= ', '.$select. ' as score ';
	}
	$sqlquery .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
		. ' WHERE i.iauthor=m.mnumber'
		. ' and i.icat=c.catid';
	$sqlquery .= $items ? ' and i.inumber in (' . implode(',', $items) . ')' : ' and 1=2 ';
	$sqlquery .= $select ? ' ORDER BY score DESC' : ' ORDER BY i.itime DESC ';
}

不安は拭いされませんが、検索結果の表示順も日時ではなくなりました。
問題なく動作しているように見えていますので、ご報告させて頂きます。


マーカーのドラッグ&ドロップでGoogle Mapsの緯度経度を測定|Geocoder
http://geocoder.heartfield-web.com/

What's so bad about feeling good?
http://blog.heartfield-web.com/

オフライン

Board footer