solr使用实例、solr结合mysql生成索引

之前有篇文章是讲述如何搭建solr的,搭建结束之后呢,我们需要简单的使用一下solr,其中solr提供了很多的客户端语言,在这里我们以php为例,简单的讲一下如何建立索引和进行搜索。
首先给出一段小例子的程序,我们使用的是solrphpclient的封装类库,第三方的solr处理类库还有solarium,也是很棒的一款类库。
[php]<?php
require_once(‘Apache/Solr/Service.php’ );
// 连接solr服务器
$solr = new Apache_Solr_Service(‘127.0.0.1’, ‘8080’, ‘/solr’);
/**如果是多核的话,想连接到某个核心,其实也就是将索引文件存放在哪里,多核的配置查看http://www.xiaotiejiang.com/archives/240
$solr = new Apache_Solr_Service(‘127.0.0.1’, ‘8080’, ‘/solr/core0’);
**/
//测试是否联通
if (!$solr->ping()) {
echo ‘Solr service not responding.’;
exit;
}

$parts = array(
‘group1’ => array(
‘id’ => 1,
‘name’ => ‘hellogxp’,
‘address’ => ‘hangzhou’,
// ‘address’ => array( ‘tiananmen’, ‘fdrfr’ ),
),
‘group2’ => array(
‘id’ => 2,
‘name’ => ‘xuguang’,
‘address’ => ‘taizhou’,
),
‘group3’ => array(
‘id’ => 3,
‘name’ => ‘aliang’,
‘address’ => ‘shaoxing’,
),
‘group4’ => array(
‘id’ => 4,
‘name’ => ‘liqiong’,
‘hobby’ => array(‘swimming’,’reading’,’music’),
)
);

foreach ($parts as $item => $fields) {
$part = new Apache_Solr_Document();
foreach ($fields as $key => $value) {
if (is_array($value)) {
foreach ($value as $datum) {
$part->setMultiValue($key, $datum);
}
} else {
$part->$key = $value;
}
}
$documents[] = $part;
}
//var_dump($documents);

// 创建索引
try {
$solr->addDocuments($documents);
$solr->commit();
$solr->optimize();
} catch (Exception $e) {
echo $e->getTraceAsString();
}

$offset = 0;
$limit = 10;
$queries = array(
‘id: 1 OR id: 2’,
‘name: hellogxp’,
‘address: shaoxing’,
‘hobby:swimming’
);
foreach ($queries as $query) {
$response = $solr->search($query, $offset, $limit,array(‘sort’=>’id desc’));
if ($response->getHttpStatus() == 200) {
if ($response->response->numFound > 0) {
foreach ($response->response->docs as $doc) {
//注意,在solr中的查询出的数据可以自由组装,例如下面就是将查询出的个人信息封装成数组,然后给$doc变量新建一个数组对象profile
$doc->profile = array(
‘name’=> $doc->name,
‘address’=> $doc->address,
‘id’=> $doc->id,
);
$info[] = $doc->profile;
//echo "$doc->address $doc->name <br />";
}
echo ‘<br />’;
}
print_r($info);
} else {
echo $response->getHttpStatusMessage();
}
}
?>[/php]
这里有个小问题,solr提供了这么强大功能,包括相似搜索(类似一些踩你喜欢,您是不是要找……之类的功能可以用到),分词功能。我么这里简单说一下solr的排序,我们先来通过solr admin来看一下,正常的solr admin的web端你会看到:http://localhost:8080/solr/select/?q=*%3A*&version=2.2&start=0&rows=10,其实我们只需要一个参数即可,在url后面加一个get参数field desc,这样子便会按照这个字段的降序排列http://localhost:8080/solr/select/?q=*%3A*&version=2.2&start=0&rows=10&sort=products_date_added%20desc,多个字段排序使用,隔开&srot=field1 desc,field2 desc,按field1字段降序排列,如果字段值相同时,再按field2字段降序排列api当中实现我们在search函数中加一个数组即可array(‘sort’=>’id desc’)。当然,如果一个字段你设置为text,就不能参与排序了,因为这个都被分词了,因此不能被作为查询排序的字段使用。没有指定 sort 参数时,搜索结果默认按文档得分(score)的降序。(desc)排列。还有一个问题就是索引的更新和重建,当你有数据更新的时候,可以进行部分更新而不需要每次都重建索引,例如你有一条数据需要更新,那么直接使用solr的add/update或者使用phpsorclient进行这一条数据的更新, 其实你使用add也不会有问题,因为在add时候solr会根据你的unique id检查数据,如果已经存在就更新,不存在就新建。
这里需要编辑solr的配置文件,我的solr安装在tomcat下面,/usr/local/tomcat/solr/conf/schema.xml
在文件
[xml]
<fields>
<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="name" type="string" indexed="true" stored="true" required="true" />
<field name="address" type="string" indexed="true" stored="true" required="true" />
<field name="hobby" type="string" multiValued="true" indexed="true" stored="true"/>
</fields>[/xml]
其中name字段不能重名。然后重启tomcat。这里注意一下,其中hobby字段有个属性multiValued设置为了true,这是因为本身原始数组中hobby这个字段就是一个数组。至于这个schemaxml中的字段的type,我们可以参考官方文档:http://wiki.apache.org/solr/SchemaXml。
刚才我们建立索引是使用的solrphpclient类,鉴于我们很多项目都是使用mysql作为关系数据库存储数据,那么我们现在讲一下如何结合solr和mysql直接将mysql中的数据生成索引。
首先solr要和mysl通信,我们使用Mysql JDBC,这个类的名字为;com.mysql.jdbc.Driver。调用URL方式为:
[shell]URL:jdbc:mysql://servername:port/database[/shell]
那么我们先下载mysql-connector-java-5.1.22-bin.jar,然后将这个文件复制到solr根目录的lib文件夹下(这个文件夹需要手动创建),我的环境下是/opt/solr/example/solr/lib这个目录。
那么除了这个插件外,我们还需要DIH,也就是dataImportHandler,这个插件是solr用来导入数据生成索引的,因此我们需要下载apache-solr-dataimporthandler-extras-3.6.1.jar和apache-solr-dataimporthandler-3.6.1.jar。这两个文件我们同样复制到/usr/local/tomcat/solr/lib这个文件夹下。
okay工具和类库已然准备好了,下面我们开始修改和创建配置文件。
首先我们需要来定义一下solr和mysql的通信,我们先修改/usr/local/tomcat/solr/conf/solrconfig.xml文件。
[shell]vim /usr/local/tomcat/solr/conf/solrconfig.xml[/shell]
在其中加入
[shell]<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>[/shell]
这个文件的作用是定义data-config.xml文件的路径,data-config.xml这个文件就是定义solr和mysql通信的相关信息。当然data-config.xml这个文件需要我们手动添加。
[shell]cd /usr/local/tomcat/solr/conf
vim data-config.xml[/shell]
在这个新建的文件中添加:
[shell]<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/demo"
user="root"
password="password"/>
<document>
<entity name="id"
query="select name from demo">
</entity>
</document>
</dataConfig>[/shell]
这个文件的信息很明显,在此不做解释。
还有一点就是如果你的数据库中查询的字段没有在shcema.xml中定义,需要先去shcema.xml定义,这个在本文有所提过,非常简单,就是添加一个字段而已。
之后我们重启tomcat,
[shell]/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh[/shell]
接下来,我们就可以测试一下索引生成的效果了:
[shell]http://localhost:8080/solr/dataimport?command=full-import[/shell]
这个表示生成新索引并且删除旧的索引,如果不删除旧的索引,可以这样:
[shell]http://localhost:8080/solr/dataimport?command=full-import&clean=false[/shell]
有一点需要注意的是,solr的索引生成是增量生成方式,也就是说如果你生成索引之前不去删除上次的索引,那么本次的索引生成将会按照唯一ID进行更新操作,如果你本次生成的数据中删除了一条,那么如果你不将上次的索引全删掉就进行索引生成,那么这条删除掉的数据还会存在,我们可以通过solr的web端进行删除:[shell]
http://xiaotiejiang.com:8080/solr/core_1/update/?stream.body=<delete><id>123456</id></delete>&stream.contentType=text/xml;charset=utf-8&commit=true[/shell]
这样你就根据唯一id删除掉了一条数据。
但是如果你的新数据中有很多删除掉的,那么不可能这样一条一条的删掉(当然,如果你愿意,可以使用curl来批量处理),我们就需要删掉data下面的所有文件夹,这时候如果你再生成也许会报错,因为这时候你需要重启tomcat服务,重启之后在data下面会重新自动生成index和spellchecker文件夹,并且index文件夹下会有文件生成( 因此即使你自己手动建立这两个文件夹也是不行的,必必须要由服务自动建立)。因此记得如果删掉索引文件重建索引,需要重启tomcat服务。
最后提及一点,solr的索引文件是在/op/solr/example/solr/data/下的index文件夹(如果你的solr是配置的多核心的就在solr/cores/core1/data/index下面),data下的文件在建立索引的时候都会自动建立。
这时候你可以从页面xml文档得到信息,例如就生成了多少条索引等。你可以使用solradmin来查看一下结果:
[shell]http://localhost:8080/solr/admin[/shell]
可以在其中输入关键字查询一下。
注:本文的所有路径都是本机安装目录和路径,具体实践请参阅自己的软体安装路径。

Avatar photo

About Blackford

这是个最好的时代,这是个最坏的时代,这是个充满希望的春天,这是个令人绝望的冬天,我们前面什么都有,我们前面什么都没有。梦想,让我们一次次的走远,又一次次的回头,一个关于人生的梦想还在不断奔跑,带着喜悦和疼痛,不过一切才刚刚开始,并且直到今天也远远没有结束
This entry was posted in PHP服务器脚本 and tagged , , , . Bookmark the permalink.

发表评论

电子邮件地址不会被公开。 必填项已用*标注