solr框架的使用-API的使用DEMO

solr控制檯相信比較容易,簡單摸索就可以學會使用了,對於後端開發人員來說還是直接用程序代碼操作直觀些,因此這次特別拿出了我的學習小例子分享給大家,demo使用springboot開發,圖片服務器使用nodejs(也可以使用nginx或者其他方式)

1 程序依賴pom和配置文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.debug</groupId>
  <artifactId>FirstSolr</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>FirstSolr</name>
  <url>http://maven.apache.org</url>

  <properties>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
  </properties>
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
  </parent>

  <dependencies>
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.1</version>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
       <dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.46</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-solr</artifactId>
		</dependency>
		
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<!-- tomcat 的支持.-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <scope>provided</scope>
    </dependency>
		
    
  </dependencies>
</project>

springboot的配置文件如下:

server.port=8090
#server.context-path=/shiro/
#server.servlet.context-path=/axmobile/
#DataBase DataSources  
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/shiro?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
  
#mybatis.typeAliasesPackage=com.debug
#mybatis.config-location=classpath:mybatis-config.xml
#mybatis.mapperLocations=classpath:/com/debug/mapper/**/*.xml

spring.data.solr.host=http://127.0.0.1:8089/solr

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
  
  
logging.level.com.debug=debug

暫時只需要指定下solr的主機地址即可,如有安全性方面的要求運行有solr環境的服務器需要做諸如防火牆、端口等的訪問限制

2 solr數據的初始化

這裏初始化幾條汽車相關的信息到solr,讓solr進行存儲和索引

package com.debug.entity;

import org.apache.solr.client.solrj.beans.Field;

public class Goods {
	
	@Field("id")
	private String id;
	
	@Field("goods_name")
	private String name;
	
	@Field("goods_price")
	private double price;
	
	@Field("goods_skuProps")
	private String[] skuProps;
	
	@Field("goods_imageUrl")
	private String imageUrl;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public String[] getSkuProps() {
		return skuProps;
	}

	public void setSkuProps(String[] skuProps) {
		this.skuProps = skuProps;
	}

	public String getImageUrl() {
		return imageUrl;
	}

	public void setImageUrl(String imageUrl) {
		this.imageUrl = imageUrl;
	}
}

上面的實體類和平時使用的差異不大,我們使用solr的註解@Filed讓實體的屬性和solr的索引名稱建立映射關係,這裏爲了研究和學習方便直接使用了自帶的幾條索引,如果不夠也可以自行到schema.xml裏面新增索引

public void initGoodsSolor() {
		List<Goods> ls0 = new ArrayList<Goods>();

		Goods g1 = new Goods();
		String skuProp[] = { "黑色", "白色" };
		g1.setId("goods_" + UUID.randomUUID().toString());
		g1.setName("新捷達");
		g1.setPrice(80000);
		g1.setSkuProps(skuProp);
		g1.setImageUrl("/images/xjd.jpg");
		ls0.add(g1);

		Goods g2 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g2.setId("goods_" + UUID.randomUUID().toString());
		g2.setName("奧迪A6");
		g2.setPrice(250000);
		g2.setSkuProps(skuProp);
		g2.setImageUrl("/images/ad.jpg");
		ls0.add(g2);

		Goods g3 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g3.setId("goods_" + UUID.randomUUID().toString());
		g3.setName("寶駿");
		g3.setPrice(250000);
		g3.setSkuProps(skuProp);
		g3.setImageUrl("/images/bj.jpg");
		ls0.add(g3);

		Goods g4 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g4.setId("goods_" + UUID.randomUUID().toString());
		g4.setName("寶來");
		g4.setPrice(110000);
		g4.setSkuProps(skuProp);
		g4.setImageUrl("/images/bl.jpg");
		ls0.add(g4);

		Goods g5 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g5.setId("goods_" + UUID.randomUUID().toString());
		g5.setName("寶馬");
		g5.setPrice(500000);
		g5.setSkuProps(skuProp);
		g5.setImageUrl("/images/bm.jpg");
		ls0.add(g5);

		Goods g6 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g6.setId("goods_" + UUID.randomUUID().toString());
		g6.setName("東風風神");
		g6.setPrice(75000);
		g6.setSkuProps(skuProp);
		g6.setImageUrl("/images/dffs.jpg");
		ls0.add(g6);

		try {
			solrClient.addBeans(ls0);
			solrClient.commit();
			// solrClient.addBeans(ls);
			// solrClient.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

solrClient從外部注入即可,後面會把這個service貼出來,大家稍安勿躁

3 實現搜索功能並把搜索關鍵字標紅

public List<Goods> queryGoods(String name, String end) {

		List<Goods> result = new ArrayList<Goods>();

		SolrQuery query = new SolrQuery();
		// 下面設置solr查詢參數
		// query.set("q", "*:*");// 參數q 查詢所有
		query.set("q", "goods_name:" + name);// 相關查詢,比如某條數據某個字段含有周、星、馳三個字 將會查詢出來 ,這個作用適用於聯想查詢

		// 過濾條件
		// query.set("fq", "price:[600 TO 1000]");

		// 參數sort,設置返回結果的排序規則
		query.setSort("goods_price", SolrQuery.ORDER.asc);

		// 設置分頁參數
		query.setStart(0);
		query.setRows(Integer.parseInt(end));// 每一頁多少值

		// 參數hl,設置高亮
		query.setHighlight(true);
		// 設置高亮的字段
		query.addHighlightField("goods_name");
		// 設置高亮的樣式
		query.setHighlightSimplePre("<font color='red'>");
		query.setHighlightSimplePost("</font>");
		// query.setParam("hl.fl", "name");
		// 獲取查詢結果
		QueryResponse response = null;
		try {
			response = solrClient.query(query);
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 兩種結果獲取:得到文檔集合或者實體對象

		// 查詢得到文檔的集合
		SolrDocumentList solrDocumentList = response.getResults();

		// System.out.println("通過文檔集合獲取查詢的結果");
		// System.out.println("查詢結果的總數量:" + solrDocumentList.getNumFound());

		List<Goods> goodsList = response.getBeans(Goods.class);
		Map<String, Map<String, List<String>>> maplist = response.getHighlighting();
		// 返回高亮之後的結果..
		for (Goods g : goodsList) {
			String id = g.getId();
			double price = g.getPrice();
			String imageUrl = g.getImageUrl();
			Map<String, List<String>> fieldMap = maplist.get(id);
			List<String> stringlist = fieldMap.get("goods_name");

			Goods g1 = new Goods();
			g1.setName(stringlist.get(0));
			g1.setPrice(new Double(price).doubleValue());
			g1.setImageUrl(imageUrl);
			result.add(g1);

		}

		return result;
	}

只要獲取到solr返回給我們的結果,下面的工作就很簡單了,無外乎就是數據展示相關了

<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查詢結果</title>
 <style type="text/css">
      ul{
        
           list-style:none;
      }
      ul li{
        text-decoration: none;float:left;margin-left:20px;
      }
      .top{
          margin-top:20px;
      }
      .goodsImg{
          width:200px;
          height:250px;
      }
    </style>
   <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
   
    
    <div class="container">
      <div class="row">
           <div class="col-md-12">
               <c:forEach var="item" items="${result}">  
	                <div class="col-md-3  top">
	                        <div><img class="goodsImg" src="http://localhost:9091${item.imageUrl}"/></div>
	                        <div>${item.name}</div>
	                </div>
                </c:forEach>  
           </div>
          
      </div>
    </div>
</body>
</html>

運行效果如下

圖片選的不是很好,界面難看了點,大家湊合看看就行

下面把controller和service的完整代碼貼出來給大家參考

package com.debug.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.solr.client.solrj.SolrClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.debug.service.SolrService;

@Controller
@RequestMapping("/solrHandler")
public class SolrController {
	
	@Resource
	private SolrService solrService;
	
	@Autowired
	private SolrClient solrClient;
	
	@RequestMapping("/initGoodsSolor")
	 @ResponseBody
	public String initGoodsSolor() {
		solrService.initGoodsSolor();
		return "操作成功";
	}
	
	@RequestMapping("/initSolr")
	 @ResponseBody
	public String initSolr() {
		solrService.initSolor();
		return "操作成功";
	}
	
	@RequestMapping("/query")
	public String query(HttpServletRequest request,String name) {
		
	      request.setAttribute("result", solrService.query(name));
		  return "query";
	}
	
	@RequestMapping("/queryGoods")
	public String queryGoods(HttpServletRequest request,String name,String end) {
		
	      request.setAttribute("result", solrService.queryGoods(name,end));
		  return "queryGoods";
	}
	
	 /**
     * 刪除所有的索引
     * @return
     */
    @RequestMapping("deleteAll")
    @ResponseBody
    public String deleteAll(){
        try {

        	solrClient.deleteByQuery("collection1","*:*");
        	solrClient.commit("collection1");

            return "success";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "error";
    }


}

 

package com.debug.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.debug.entity.Goods;
import com.debug.service.SolrService;

@Service
public class SolrServiceImpl implements SolrService {

	@Autowired
	private SolrClient solrClient;

	public void initSolor() {
		List<SolrInputDocument> ls0 = new ArrayList<SolrInputDocument>();
		for (int i = 1; i <= 10; i++) {

			SolrInputDocument doc = new SolrInputDocument();
			doc.setField("id", "goods_" + i);
			doc.setField("name", "手機" + i);
			doc.setField("price", new Random().nextInt(1000));
			doc.setField("description", "產品介紹" + i);
			ls0.add(doc);

		}
		List<SolrInputDocument> ls = new ArrayList<SolrInputDocument>();
		for (int i = 1; i <= 10; i++) {

			SolrInputDocument doc = new SolrInputDocument();
			doc.setField("id", "goods_" + 10 + i);
			doc.setField("name", "筆記本電腦" + i);
			doc.setField("price", new Random().nextInt(1000));
			doc.setField("description", "產品介紹" + i);

			ls.add(doc);

		}
		try {
			solrClient.add(ls0);
			solrClient.add(ls);
			solrClient.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// solrClient.close();

	}

	public List<String> query(String name) {

		List<String> result = new ArrayList<String>();

		SolrQuery query = new SolrQuery();
		// 下面設置solr查詢參數
		// query.set("q", "*:*");// 參數q 查詢所有
		query.set("q", "name:" + name);// 相關查詢,比如某條數據某個字段含有周、星、馳三個字 將會查詢出來 ,這個作用適用於聯想查詢

		// 過濾條件
		query.set("fq", "price:[600 TO 1000]");

		// 參數sort,設置返回結果的排序規則
		query.setSort("id", SolrQuery.ORDER.asc);

		// 設置分頁參數
		query.setStart(0);
		query.setRows(10);// 每一頁多少值

		// 參數hl,設置高亮
		query.setHighlight(true);
		// 設置高亮的字段
		query.addHighlightField("name");
		// 設置高亮的樣式
		query.setHighlightSimplePre("<font color='red'>");
		query.setHighlightSimplePost("</font>");
		// query.setParam("hl.fl", "name");
		// 獲取查詢結果
		QueryResponse response = null;
		try {
			response = solrClient.query(query);
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 兩種結果獲取:得到文檔集合或者實體對象

		// 查詢得到文檔的集合
		// SolrDocumentList solrDocumentList = response.getResults();

		// System.out.println("通過文檔集合獲取查詢的結果");
		// System.out.println("查詢結果的總數量:" + solrDocumentList.getNumFound());

		SolrDocumentList documentList = response.getResults();
		Map<String, Map<String, List<String>>> maplist = response.getHighlighting();
		// 返回高亮之後的結果..
		for (SolrDocument solrDocument : documentList) {
			Object id = solrDocument.get("id");
			Map<String, List<String>> fieldMap = maplist.get(id);
			List<String> stringlist = fieldMap.get("name");

			result.add(stringlist.get(0));
			// System.out.println(stringlist);
		}

		return result;
	}

	public void initGoodsSolor() {
		List<Goods> ls0 = new ArrayList<Goods>();

		Goods g1 = new Goods();
		String skuProp[] = { "黑色", "白色" };
		g1.setId("goods_" + UUID.randomUUID().toString());
		g1.setName("新捷達");
		g1.setPrice(80000);
		g1.setSkuProps(skuProp);
		g1.setImageUrl("/images/xjd.jpg");
		ls0.add(g1);

		Goods g2 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g2.setId("goods_" + UUID.randomUUID().toString());
		g2.setName("奧迪A6");
		g2.setPrice(250000);
		g2.setSkuProps(skuProp);
		g2.setImageUrl("/images/ad.jpg");
		ls0.add(g2);

		Goods g3 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g3.setId("goods_" + UUID.randomUUID().toString());
		g3.setName("寶駿");
		g3.setPrice(250000);
		g3.setSkuProps(skuProp);
		g3.setImageUrl("/images/bj.jpg");
		ls0.add(g3);

		Goods g4 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g4.setId("goods_" + UUID.randomUUID().toString());
		g4.setName("寶來");
		g4.setPrice(110000);
		g4.setSkuProps(skuProp);
		g4.setImageUrl("/images/bl.jpg");
		ls0.add(g4);

		Goods g5 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g5.setId("goods_" + UUID.randomUUID().toString());
		g5.setName("寶馬");
		g5.setPrice(500000);
		g5.setSkuProps(skuProp);
		g5.setImageUrl("/images/bm.jpg");
		ls0.add(g5);

		Goods g6 = new Goods();
		// String skuProp[]= {"黑色","白色"};
		g6.setId("goods_" + UUID.randomUUID().toString());
		g6.setName("東風風神");
		g6.setPrice(75000);
		g6.setSkuProps(skuProp);
		g6.setImageUrl("/images/dffs.jpg");
		ls0.add(g6);

		try {
			solrClient.addBeans(ls0);
			solrClient.commit();
			// solrClient.addBeans(ls);
			// solrClient.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public List<Goods> queryGoods(String name, String end) {

		List<Goods> result = new ArrayList<Goods>();

		SolrQuery query = new SolrQuery();
		// 下面設置solr查詢參數
		// query.set("q", "*:*");// 參數q 查詢所有
		query.set("q", "goods_name:" + name);// 相關查詢,比如某條數據某個字段含有周、星、馳三個字 將會查詢出來 ,這個作用適用於聯想查詢

		// 過濾條件
		// query.set("fq", "price:[600 TO 1000]");

		// 參數sort,設置返回結果的排序規則
		query.setSort("goods_price", SolrQuery.ORDER.asc);

		// 設置分頁參數
		query.setStart(0);
		query.setRows(Integer.parseInt(end));// 每一頁多少值

		// 參數hl,設置高亮
		query.setHighlight(true);
		// 設置高亮的字段
		query.addHighlightField("goods_name");
		// 設置高亮的樣式
		query.setHighlightSimplePre("<font color='red'>");
		query.setHighlightSimplePost("</font>");
		// query.setParam("hl.fl", "name");
		// 獲取查詢結果
		QueryResponse response = null;
		try {
			response = solrClient.query(query);
		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 兩種結果獲取:得到文檔集合或者實體對象

		// 查詢得到文檔的集合
		SolrDocumentList solrDocumentList = response.getResults();

		// System.out.println("通過文檔集合獲取查詢的結果");
		// System.out.println("查詢結果的總數量:" + solrDocumentList.getNumFound());

		List<Goods> goodsList = response.getBeans(Goods.class);
		Map<String, Map<String, List<String>>> maplist = response.getHighlighting();
		// 返回高亮之後的結果..
		for (Goods g : goodsList) {
			String id = g.getId();
			double price = g.getPrice();
			String imageUrl = g.getImageUrl();
			Map<String, List<String>> fieldMap = maplist.get(id);
			List<String> stringlist = fieldMap.get("goods_name");

			Goods g1 = new Goods();
			g1.setName(stringlist.get(0));
			g1.setPrice(new Double(price).doubleValue());
			g1.setImageUrl(imageUrl);
			result.add(g1);

		}

		return result;
	}

}

使用到的索引如下:

<field name="goods_name" type="text_general" indexed="true" stored="true"/>
<field name="goods_price" type="float" indexed="true" stored="true"/>
<field name="goods_skuProps" type="text_general" indexed="true" stored="true" multiValued="true"/>
<field name="goods_imageUrl" type="text_general" indexed="true" stored="true" multiValued="false"/>

是不是很簡單呢,現在除了solr外我們還可以選擇Elasticsearch作爲搜索引擎,可參考下面這個學習

https://www.imooc.com/learn/889/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章