Slor的使用(单机,集群)(后续es)

⦁ solr服务搭建

⦁ solr环境准备


    Solr是java开发的,需要安装jdk。
    需要solr的安装文件。
    安装环境Linux。
    需要安装Tomcat。

⦁ solr安装

第二步:解压solr。
第三步:安装Tomcat,解压缩即可。
第四步:把solr部署到Tomcat下。
第五步:解压缩war包。可以启动Tomcat解压。
第六步:把/root/solr-4.10.3/example/lib/ext目录下的所有的jar包,添加到solr工程中。
[[email protected] ext]# pwd
/root/solr-4.10.3/example/lib/ext
[[email protected] ext]# cp * /usr/local/solr/tomcat/webapps/solr/WEB-INF/lib/
第七步:创建一个(mkdir)solrhome。/example/solr目录就是一个solrhome。复制此目录到/usr/local/solr/solrhome
[[email protected] example]# pwd
/root/solr-4.10.3/example
[[email protected] example]# cp -r solr /usr/local/solr/solrhome
[[email protected] example]#
第八步:关联solr及solrhome。需要修改solr工程的web.xml文件。
 Slor的使用(单机,集群)(后续es)
第九步:启动Tomcat
http://192.168.25.154:8080/solr/
和windows下的配置完全一样。

⦁ solr的使用

添加文档必须有id域,其他域 必须在solr的schema.xml中定义。

⦁ 添加中文分词器


第一步:把中文分析器添加到solr工程中。
1) 把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目录下
2) 把扩展词典、停用词词典,配置文件放到solr工程的WEB-INF/classes目录下。
第二步:配置一个FieldType,制定使用IKAnalyzer
修改schema.xml文件
修改Solr的schema.xml文件,添加FieldType:
<fieldType name="text_ik" class="solr.TextField">
  <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>

⦁ 配置业务域


schema.xml中定义(根据需求)
1) 商品Id  使用schema.xml中的id域
2) 商品标题
3) 商品卖点
4) 商品价格
5) 商品图片
6) 分类名称
7) 商品描述
配置业务域,type指定使用自定义的FieldType。
⦁ 设置业务系统Field
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price"  type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_desc" type="text_ik" indexed="true" stored="false" />
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>
<copyField source="item_desc" dest="item_keywords"/>
......重启tomcat
⦁ 测试使用solrJ管理索引库
使用SolrJ可以实现索引库的增删改查操作。
⦁ 添加文档
第一步:把solrJ的jar包添加到工程中。
第二步:创建一个SolrServer,使用HttpSolrServer创建对象。
第三步:创建一个文档对象SolrInputDocument对象。
第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
第五步:把文档添加到索引库中。
第六步:提交。
@Test
 public void addDocument() throws Exception {
  // 第一步:把solrJ的jar包添加到工程中。
  // 第二步:创建一个SolrServer,使用HttpSolrServer创建对象。
  SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
  // 第三步:创建一个文档对象SolrInputDocument对象。
  SolrInputDocument document = new SolrInputDocument();
  // 第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。
  document.addField("id", "test001");
  document.addField("item_title", "测试商品");
  document.addField("item_price", "199");
  // 第五步:把文档添加到索引库中。
  solrServer.add(document);
  // 第六步:提交。
  solrServer.commit();
 }
⦁ 删除文档
⦁ 根据id删除
第一步:创建一个SolrServer对象。
第二步:调用SolrServer对象的根据id删除的方法。
第三步:提交。
@Test
 public void deleteDocumentById() throws Exception {
  // 第一步:创建一个SolrServer对象。
  SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
  // 第二步:调用SolrServer对象的根据id删除的方法。
  solrServer.deleteById("1");
  // 第三步:提交。
  solrServer.commit();
 }
⦁ 根据查询删除
@Test
 public void deleteDocumentByQuery() throws Exception {
  SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
  solrServer.deleteByQuery("title:change.me");
  solrServer.commit();
 }
⦁ 查询索引库
查询步骤:
第一步:创建一个SolrServer对象
第二步:创建一个SolrQuery对象。
第三步:向SolrQuery中添加查询条件、过滤条件。。。
第四步:执行查询。得到一个Response对象。
第五步:取查询结果。
第六步:遍历结果并打印。
⦁ 简单查询
@Test
 public void queryDocument() throws Exception {
  // 第一步:创建一个SolrServer对象
  SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
  // 第二步:创建一个SolrQuery对象。
  SolrQuery query = new SolrQuery();
  // 第三步:向SolrQuery中添加查询条件、过滤条件。。。
  query.setQuery("*:*");
  // 第四步:执行查询。得到一个Response对象。
  QueryResponse response = solrServer.query(query);
  // 第五步:取查询结果。
  SolrDocumentList solrDocumentList = response.getResults();
  System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
  // 第六步:遍历结果并打印。
  for (SolrDocument solrDocument : solrDocumentList) {
   System.out.println(solrDocument.get("id"));
   System.out.println(solrDocument.get("item_title"));
   System.out.println(solrDocument.get("item_price"));
  }
 }
⦁ 带高亮显示
@Test
 public void queryDocumentWithHighLighting() throws Exception {
  // 第一步:创建一个SolrServer对象
  SolrServer solrServer = new HttpSolrServer("http://192.168.25.154:8080/solr");
  // 第二步:创建一个SolrQuery对象。
  SolrQuery query = new SolrQuery();
  // 第三步:向SolrQuery中添加查询条件、过滤条件。。。
  query.setQuery("测试");
  //指定默认搜索域
  query.set("df", "item_keywords");
  //开启高亮显示
  query.setHighlight(true);
  //高亮显示的域
  query.addHighlightField("item_title");
  query.setHighlightSimplePre("<em>");
  query.setHighlightSimplePost("</em>");
  // 第四步:执行查询。得到一个Response对象。
  QueryResponse response = solrServer.query(query);
  // 第五步:取查询结果。
  SolrDocumentList solrDocumentList = response.getResults();
  System.out.println("查询结果的总记录数:" + solrDocumentList.getNumFound());
  // 第六步:遍历结果并打印。
  for (SolrDocument solrDocument : solrDocumentList) {
   System.out.println(solrDocument.get("id"));
   //取高亮显示
   Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
   List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
   String itemTitle = null;
   if (list != null && list.size() > 0) {
    itemTitle = list.get(0);
   } else {
    itemTitle = (String) solrDocument.get("item_title");
   }
   System.out.println(itemTitle);
   System.out.println(solrDocument.get("item_price"));
  }
 }

⦁ 导入数据到索引库中
⦁ 功能分析
要实现搜索功能,需要从索引库中查询 数据,先需要导入数据到索引库中,那么就可以在demo_manager_web后台管理系统中添加一个按钮 ,点击时一键导入数据到索引库中。
 
Slor的使用(单机,集群)(后续es)
业务逻辑:
1.点击按钮,表现层调用服务层的工程的导入索引库的方法
2.服务层实现 调用mapper接口的方法查询所有的商品的数据
3.将数据一条条添加到solrinputdocument文档中
4.将文档添加到索引库中
5.提交,并返回导入成功即可
⦁ dao的开发

⦁ 分析
在schema.xml中定义以下业务域(已经定义好):
商品Id
商品标题
商品卖点
商品价格
商品图片
分类名称
商品描述
需要从tb_item, tb_item_cat, tb_item_desc表中查询数据。
Sql语句:
SELECT
 a.id,
 a.title,
 a.sell_point,
 a.price,
 a.image,
 b. NAME category_name,
 c.item_desc
FROM
 tb_item a,
 tb_item_cat b,
 tb_item_desc c
WHERE
 a.cid = b.id
AND a.id = c.item_id
AND a.`status` = 1;

⦁ 编写映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.taotao.search.mapper.SearchItemMapper" >
   <select id="getSearchItemList" resultType="com.taotao.common.pojo.SearchItem">
      SELECT
         a.id,
         a.title,
         a.sell_point,
         a.price,
         a.image,
         b.`name` AS category_name,
         c.item_desc
      FROM
         tb_item a,
         tb_item_cat b,
         tb_item_desc c
      WHERE
         a.cid = b.id
      AND c.item_id = a.id
      AND a.`status` = 1
   </select>
  
   <select id="getSearchItemById"  parameterType="long" resultType="com.taotao.common.pojo.SearchItem">
      SELECT
         a.id,
         a.title,
         a.sell_point,
         a.price,
         a.image,
         b.`name` AS category_name,
         c.item_desc
      FROM
         tb_item a,
         tb_item_cat b,
         tb_item_desc c
      WHERE
         a.cid = b.id
      AND c.item_id = a.id
      AND a.`status` = 1
      AND a.id=#{id}
   </select>
</mapper>


业务代码:

@Override
public DemoResult importAllIndex() throws Exception{
  
   //从数据库中查询所有的商品的数据 ,导入数据到索引库中  用solrj
  
   //1.创建连接对象solrserver 由spring管理
  
   //2.调用MApper的方法 返回的是List<sarchItem>
   List<SearchItem> itemList = searchitemmapper.getSearchItemList();
   //3.遍历
   List<SolrInputDocument> documents = new ArrayList<>();
   for (SearchItem searchItem : itemList) {
      //4 将集合中的数据  一个个 sarchItem 放入solrinputdocument
      SolrInputDocument document = new SolrInputDocument();
      document.addField("id", searchItem.getId().toString());
      document.addField("item_title", searchItem.getTitle());
      document.addField("item_sell_point", searchItem.getSell_point());
      document.addField("item_image", searchItem.getImage());
      document.addField("item_category_name", searchItem.getCategory_name());
      document.addField("item_price", searchItem.getPrice());
      document.addField("item_desc", searchItem.getItem_desc());
      documents.add(document);
   }
   //5.添加文档到索引库中
   solrserver.add(documents);
  
   //6.提交
   solrserver.commit();
  
   return DemoResult.ok();
}



⦁ 创建配置文件applicationContext-solr.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
  
  <-- <bean class="org.apache.solr.client.solrj.impl.HttpSolrServer">
      <constructor-arg name="baseURL" value="http://192.168.25.154:8080/solr/"></constructor-arg>
   </bean>-->
  
   <bean class="org.apache.solr.client.solrj.impl.CloudSolrServer">
  
      <constructor-arg name="zkHost" value="192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183"></constructor-arg>
      <property name="defaultCollection" value="collection2"></property>
   </bean> 
</beans>


完成;





查询:
请求的url:/search   
http://localhost:8085/search.html?q=
参数:
1、q 查询条件。
2、page 当前页码。默认为1   每页显示多少行rows 在controller中写死即可。比如:60
返回值: String。(商品的列表信息,总页数 ,总记录数,数据回显)
业务逻辑:
1) 接收查询条件。
2) 创建一个SolrServer对象,需要注入。
3) 创建一个SolrQuery对象。
4) 需要设置查询条件、分页条件、设置默认搜索域、高亮设置。
5) 执行查询,返回QueryResponse对象。
6) 取返回结果,封装到List<SearchItem>中。
7) 返回查询结果的总记录数,计算查询结果的总页数。
8) 得到查询结果,渲染jsp.


业务代码DAO层:
@Repository
public class SearchDao {
 @Autowired
 private SolrServer solrServer;
 
 public SearchResult search(SolrQuery query) throws Exception {
  //根据query对象查询索引库
  QueryResponse response = solrServer.query(query);
  //取商品列表
  SolrDocumentList solrDocumentList = response.getResults();
  //商品列表
  List<SearchItem> itemList = new ArrayList<>();
  for (SolrDocument solrDocument : solrDocumentList) {
   SearchItem item = new SearchItem();
   item.setId(Long.parseLong((String)solrDocument.get("id")));
   item.setCategory_name((String) solrDocument.get("item_category_name"));
   item.setImage((String) solrDocument.get("item_image"));
   item.setPrice((long) solrDocument.get("item_price"));
   item.setSell_point((String) solrDocument.get("item_sell_point"));
   //取高亮显示
   Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
   List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
   String itemTitle = "";
   //有高亮显示的内容时。
   if (list != null && list.size() > 0) {
    itemTitle = list.get(0);
   } else {
    itemTitle = (String) solrDocument.get("item_title");
   }
   item.setTitle(itemTitle);
   //添加到商品列表
   itemList.add(item);
  }
  SearchResult result = new SearchResult();
  //商品列表
  result.setItemList(itemList);
  //总记录数
  result.setRecordCount(solrDocumentList.getNumFound());
  
  return result;
 }
}



参数:queryString:查询条件
      Page:页码
      Rows:每页显示的记录数。
业务逻辑:
1) 创建一个SolrQuery对象。
2) 设置查询条件
3) 设置分页条件
4) 需要指定默认搜索域。
5) 设置高亮
6) 执行查询,调用SearchDao。得到SearchResult
7) 需要计算总页数。
8) 返回SearchResult

service层业务代码:

@Override
public SearchResult search(String queryString, Integer page, Integer rows)  throws Exception{
   //封装solrquery对象(设置各种的查询的条件)  调用dao的方法  返回searchresult(只有总记录书  和商品的列表)  这里添加 补全其他的属性(总页数 ..)
  
   //1.创建查询的对象Solrquery
   SolrQuery query = new SolrQuery();
   //2.设置查询的主查询条件
   if(StringUtils.isNotBlank(queryString)){
      query.setQuery(queryString);
   }else{
      query.setQuery("*:*");
   }
   //3.设置过滤条件
  
   //3.1设置分页查询的条件
   if(page==null) page=1;
   if(page<1) page=1;
   if(rows==null) rows=60;
  
   query.setStart((page-1) * rows);//(page-1) * rows
  
   query.setRows(rows);
   //3.2设置默认的搜索域
  
   query.set("df", "item_keywords");
  
   //3.3 开启高亮 设置高亮显示的域 设置前缀和后缀
   query.setHighlight(true);
   query.addHighlightField("item_title");
   query.setHighlightSimplePre("<em style=\"color:red\">");
   query.setHighlightSimplePost("</em>");
   //4.注入dao  调用dao的方法
   SearchResult result = dao.search(query);
  
   //5.设置searchresult 对象  返回
  
   long pageCount = result.getRecordCount()/rows;
  
   if( result.getRecordCount()% rows>0){
      pageCount++;
   }
   result.setPageCount(pageCount );
  
  
   return result;
}