• 1
  • 2
  • 3
  • 4
  • 5
mysql數據庫問題 首 頁  ?  幫助中心  »  數據庫  »  mysql數據庫問題
PHP+MongoDB+Coreseek/Sphinx打造搜索引擎
發布日期:2016-4-30 13:4:7

 近幾年來,Linux+Nginx+PHP+MongoDB(LNPM)這樣的組合越來越火,甚至有取代Linux+Nginx/Apache+PHP+mysql這種組合的趨勢。究其原因,是MongoDB強大,靈活,易擴展,更關鍵的易用。MongoDB不用事先設計好表結構,往里面插入什么都可以,管理還方便。所以成為創業團隊的首選數據庫,更是移動互聯網的一枝新秀。

  但MongoDB和關系型數據庫也有很多相似之處,如全文索引不支持中文。在MongoDB2.6版本中開始默認支持全文索引,一如既往的不支持偉大的Chinese,因此如果需要搜索功能,就要另辟蹊徑。

  Sphinx與Lucene是做搜索引擎的不錯的選擇。個人觀點Lucene對Java的支持比較好,而Sphixn對PHP的支持較好,所以我選擇了Sphinx。其實Sphinx對中文的支持也不是很好,由于Sphinx是根據空格來分詞(適用與英文),根本不適用中文分詞。幸好有人提供了基于Sphinx的支持中文的插件Coreseek和Sphinx—for—chinese。

  Coreseek有完整的文檔,目前支持最新版的Sphinx,因此我選擇Coreseek。

  Sphinx-for-chinese嚴重缺乏文檔。

  安裝:

 ?。?)Coreseek安裝。

 ?。?)phinx-for-chinese安裝。

  創建索引:

  Coreseek支持與Mysql直接對接,只需在Coreseek配置文件里填上Mysql的信息,Coreseek就會自動讀取Mysql數據來創建索引(當然前提是你做了生成索引的相應設置或者執行生成索引的命令)。但是Sphinx不支持與MongoDB直接對接,可以把Mongo數據源轉換為Python數據源或者轉換成xmlpipe2數據源。

  本人不會Python,因此用php些了一個xml管道用于把MongoDB數據傳輸到Coreseek。參考代碼如下所示:

  class SphinxXmlpipe{

  private $xmlWriter;

  private $fields = array();

  private $attributes = array();

  private $documents = array();

  public function setFields($fields) {

  $this->fields = $fields;

  }

  public function setAttributes($attributes) {

  $this->attributes = $attributes;

  }

  public function beginOutput() {

  //create a new xml document

  $this->xmlWriter = new \XMLWriter();

  $this->xmlWriter->openMemory();

  $this->xmlWriter->setIndent(true);

  $this->xmlWriter->startDocument('1.0', 'UTF-8');

  $this->xmlWriter->startElement('sphinx:docset');

  $this->xmlWriter->startElement('sphinx:schema');

  // add fileds to the schma

  foreach($this->fields as $field) {

  $this->xmlWriter->startElement('sphinx:field');

  $this->xmlWriter->writeAttribute('name', $field);

  $this->xmlWriter->endElement();

  }

  /*

  // add atttributes to the schema

  foreach($this->attributes as $attributes) {

  $this->xmlWriter->startElement('sphinx:attr');

  foreach($attributes as $key => $value) {

  $this->xmlWriter->writeAttribute($key, $value);

  }

  $this->xmlWriter->endElement();

  }

  */

  $this->xmlWriter->endElement(); // schema

  }

  public function addDocument($doc) {

  $this->xmlWriter->startElement('sphinx:document');

  $this->xmlWriter->writeAttribute('id', $doc['book_id']);

  foreach($doc as $key => $value) {

  $this->xmlWriter->startElement($key);

  $this->xmlWriter->text($value);

  $this->xmlWriter->endElement();

  }

  $this->xmlWriter->endElement(); // document

  }

  public function endOutput() {

  // end sphinx:docset

  $this->xmlWriter->endElement();

  $this->xmlWriter->endDocument();

  echo $this->xmlWriter->outputMemory();

  }

  public function xmlpipe2() {

  $this->setfields( array(

  'book_id',

  'book_name',

  ));

  $this->setAttributes( array(

  array(

  'name' => 'book_id',

  'type' => 'int',

  'bits' => '16',

  'default' => '1',

  ),

  ));

  $this->beginOutput();

  $mBook = D('book');

  $count = $mBook->count();

  $limit = c('XMLPIPE_BOOKS_COUNT_PER_TIME');

  $tCont = (int)$count/$limit;

  $oCount = $count%$limit;

  if($tCont>0) {

  do {

  $books = $mBook->field('book_id,book_name','_id=>0')->limit($limit)->select();

  foreach($books as $book) {

  $this->addDocument($book);

  }

  unset($books);

  $tCont--;

  } while($tCont>0);

  $books = $mBook->field('book_id,book_name','_id=>0')->limit($oCount)->select();

  foreach($books as $book) {

  $this->addDocument($book);

  }

  unset($books);

  } else {

  $books = $mBook->field('book_id,book_name','_id=>0')->limit($oCount)->select();

  foreach($books as $book) {

  $this->addDocument($book);

  }

  unset($books);

  }

  $this->endOutput();

  }

  }

  輸出的xml格式如下所示


圖1

  相應的Coreseek設置,參考代碼如下所示:

  source src1

  {

  type = xmlpipe2

  xmlpipe_command = cd /var/www/PHPParser && php index.php /Home/SphinxXmlpipe/xmlpipe2

  xmlpipe_field = book_id

  xmlpipe_field = book_name

  xmlpipe_attr_timestamp = book_id

  xmlpipe_attr_uint = book_id

  xmlpipe_fixup_utf8 = 1

  }

  搜索:

 ?。?)PHP提供了Sphinx擴展,適用于Coreseek。

 ?。?)phinx 安裝包提供了sphinxapi,在api目錄下。

  我用的PHP擴展

  sphinx搜索代碼。參考代碼如下所示:

  public function getResultBySearchText($search_text) {

  $sphinxClient = new \SphinxClient();

  $sphinxClient->setServer('localhost', 9312); // server = localhost,port = 9312.

  $sphinxClient->setMatchMode(SPH_MATCH_ANY);

  $sphinxClient->setMaxQueryTime(5000); // set search time 5 seconds.

  $result = $sphinxClient->query($search_text);

  if(isset($result['matches'])) {

  $rel['time'] = $result['time'];

  $rel['matches'] = $result['matches'];

  return $rel;

  } else {

  $rel['time'] = $result['time'];

  return $rel;

  }

  }

  因為用的xmlpipe數據源,所以返回的是文檔id,還需根據id去mongo提取數據。至于如何提取mongo數據,我就不寫了。

什么行业的讲师最赚钱 网络营销什么赚钱 二四六精选天天好彩挂牌 35选7头奖几率 黑龙江22选5投注技巧 钱龙捕鱼一直黑怎么办 湖南麻将打红中怎么打呼的快 现金手机捕鱼游戏大厅 心悦麻将下载 经典股票论坛 快乐扑克复式