通过前面几节的了解,我们对 solr 有了一些了解,对一些基本概念、语法也有了初步的认识,那么很多没有接触过搜索引擎的小伙伴可能会问,这东西到底有什么用,在自己的项目中能发挥什么作用,结合我们自己的项目,简要做个演示。

需求分析

相信很多人都用过类似淘宝或者京东的产品搜索功能,输入想要查找的商品,点搜索很快列出一堆你想要的东东,我们的产品也想实现这个功能。

我们都知道数据库的瓶颈主要在 IO 这块,虽然通过分库分表能分担一部分负载,但当网站访问量比较大的时候,不应该也不可能搜索一次都去执行一次数据库 IO 操作,这个时候 Solr 也就派上用途了,我们可以通过将产品相关数据刷到 Solr 的搜索实例中,通过 Solr 应用服务器对外提供 Rest 查询接口,定时去更新数据,刷新搜索索引,这样就大大降低了查询数据库服务器的压力。

数据导入

那么问题来了,如果将数据库相关数据导入搜索实例中呢?前面我们使用了 bin/post 将 json 文档直接导入搜索实例,接下来我们看下如何将 mysql 中表数据导入到搜索实例中。

使用DIH(DataImportHandler)从数据库导入数据

  1. 首先数据库准备一张表

     CREATE TABLE `comment` (
         `id` INT(11) NULL DEFAULT NULL,
         `writetime` VARCHAR(50) NULL DEFAULT NULL,
         `title` VARCHAR(500) NULL DEFAULT NULL
     )
    
  2. 往表里面插入几条测试数据

     INSERT INTO `test`.`comment` (`id`, `writetime`, `title`) VALUES (10001, '2015-04-11', 'Step 1: Set up a personal account');
     INSERT INTO `test`.`comment` (`id`, `writetime`, `title`) VALUES (10002, '2015-04-12', 'Step 2: Choose your plan');
     INSERT INT3 `test`.`comment` (`id`, `writetime`, `title`) VALUES (10003, '2015-04-13', 'Step 3: Go to your dashboard');
     INSERT INTO `test`.`comment` (`id`, `writetime`, `title`) VALUES (10004, '2015-04-14', 'There were problems creating your account.');
     INSERT INTO `test`.`comment` (`id`, `writetime`, `title`) VALUES (10005, '2015-04-15', 'You will occasionally receive account related emails. We promise not to share your email with anyone.');
     INSERT INTO `test`.`comment` (`id`, `writetime`, `title`) VALUES (10006, '2015-04-16', 'Use at least one lowercase letter, one numeral, and seven characters.');
    
  3. 导入相关jar包 在 solr-5.0.0/server/solr/test/conf/solrconfig.xml 加入如下代码

     <lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar" />
    
  4. 配置handler 在 solr-5.0.0/server/solr/test/conf/solrconfig.xml 加入如下代码

     <requestHandler name="/dataimport" class="solr.DataImportHandler">	
         <lst name="defaults">	
           <str name="config">db-data-config.xml</str>	
         </lst>	
     </requestHandler>
    
  5. 配置数据源,源数据与索引的隐射关系 在 solr-5.0.0/server/solr/test/conf/下新建db-data-config.xml ,配置如下:

     <dataConfig>
        <dataSource type="JdbcDataSource" 
                   driver="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost/test" 
                   user="root" 
                   password="root"/>
        <document>
         <entity name="comment" 
         query="SELECT id, DATE_FORMAT(writetime, '%Y-%m-%dT%TZ') as 'writetime', title from comment"
         deltaImportQuery="SELECT id, DATE_FORMAT(writetime, '%Y-%m-%dT%TZ') as 'writetime', title from comment where id='${dih.delta.id}'"
         deltaQuery="SELECT id FROM comment WHERE DATE(updatetime) >= '${dih.last_index_time}' OR DATE(writetime) >= '${dih.last_index_time}'">       
            <field column="id" name="id"/>      
            <field column="writetime" name="writetime"/>
            <field column="title" name="title"/>           
         </entity>      
       </document>
     </dataConfig>
    

注:查询 sql 可以是多表关联查询,只要查询字段跟下面的 field 对应起来就可以。另外 field 对应的name值必须在 config 目录下的 schema.xml 文件中存在。如上述的 writetime 不存在,则在schema.xml中添加

	<field name="writetime" type="tdate" indexed="true" stored="true"/>

indexed 表示需不需要建立索引,以便之后对这个 field 进行查询;

stored 表示需不需要随索引同时存储这个 field 本身的内容,以便查询时直接从结果中获取该内容,一般大数据(比如文件内容本身)不会和索引一起保存,节省资源,防止索引过大。 索引本身和被索引的内容要分清,不理解的话,倒排索引:http://zh.wikipedia.org/wiki/倒排索引

6.Reload test 搜索实例,利用图形界面执行dataimport

Web 控制台 dataimport

因为这个文件我已经导过了,所以上面显示是 reload,第一次使用时有一点点差别。导完数据以后我们查询验证下 http://localhost:8080/solr/test/select?q=title%3Astep&wt=json&indent=true

返回结果:

{
  "responseHeader":{
    "status":0,
    "QTime":2,
    "params":{
      "indent":"true",
      "q":"title:step",
      "wt":"json"}},
  "response":{"numFound":3,"start":0,"docs":[
      {
        "id":"10002",
        "title":["Step 2: Choose your plan"],
        "writetime":"2015-04-10T00:00:00Z",
        "_version_":1498574060831899648},
      {
        "id":"10001",
        "title":["Step 1: Set up a personal account"],
        "writetime":"2015-04-10T00:00:00Z",
        "_version_":1498574060739624960},
      {
        "id":"10003",
        "title":["Step 3: Go to your dashboard"],
        "writetime":"2015-04-10T00:00:00Z",
        "_version_":1498574060832948224}]
  }}

这里面我们使用的是 title:step 将 title 包含 step 的三条记录都查了出来。

编程的方式来自定义导入(这个编程部分再讲)

当然除了数据库数据,Solr 还能导入 csv,json,word,pdf,这部分有兴趣可以自己去试验下。

至此,一个简单的 Solr 的应用演示算是完成了。