作為一般的Lucene使用者,我們直接用Lucene雖然可以實(shí)現(xiàn)很多自己想要的自定義功能曲秉,但是對(duì)于一般的項(xiàng)目,為了方便開(kāi)發(fā)和維護(hù)歧譬,我們通常會(huì)使用現(xiàn)成的搜索服務(wù)器“痘耄現(xiàn)在常用的有Solr和ElasticSearch。
對(duì)于Solr服務(wù)器如何搭建瑰步,Solr服務(wù)器的搭建矢洲,之前已經(jīng)整理過(guò),這次缩焦,我將使用SolrJ來(lái)調(diào)用Solr服務(wù)器读虏。
在Solr中配置Core
在managed-schema中,主要的配置為:
<uniqueKey>blogId</uniqueKey>
<field name="blogId" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="blogTitle" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" />
<field name="blogContent" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" />
<field name="createTime" type="date" indexed="false" stored="true" required="true" multiValued="false" />
<field name="keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="blogTitle" dest="keywords"/>
<copyField source="blogContent" dest="keywords"/>
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" useSmart="false"
class="org.wltea.analyzer.lucene.IKAnalyzer" />
<analyzer type="query" useSmart="true"
class="org.wltea.analyzer.lucene.IKAnalyzer" />
</fieldType>
依賴(lài)
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>6.5.1</version>
</dependency>
SolrServer.Java
package top.yuyufeng.learn.lucene.solr;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
/**
* @author yuyufeng
* @date 2017/12/6
*/
public class SolrServer {
private static HttpSolrClient server = null;
private final static String solrServerUrl = "http://127.0.0.1:8983/solr/blog";
public static HttpSolrClient getServer() {
if (server == null) {
server = new HttpSolrClient(solrServerUrl);
server.setDefaultMaxConnectionsPerHost(1000);
server.setMaxTotalConnections(10000);//最大連接數(shù)
server.setConnectionTimeout(60000);//設(shè)置連接超時(shí)時(shí)間(單位毫秒) 1000
server.setSoTimeout(60000);//// 設(shè)置讀數(shù)據(jù)超時(shí)時(shí)間(單位毫秒) 1000
server.setFollowRedirects(false);//遵循從定向
server.setAllowCompression(true);//允許壓縮
}
return server;
}
public static void main(String[] args) {
HttpSolrClient client = getServer();
System.out.println(client);
}
}
BlogCore.java
package top.yuyufeng.learn.lucene.solr.core;
import org.apache.solr.client.solrj.beans.Field;
import java.util.Date;
/**
* @author yuyufeng
* @date 2017/12/6
*/
public class BlogCore {
@Field
private String blogId;
@Field
private String blogTitle;
@Field
private String blogContent;
@Field
private Date createTime;
@Field
private String keywords;
public String getBlogId() {
return blogId;
}
public void setBlogId(String blogId) {
this.blogId = blogId;
}
public String getBlogTitle() {
return blogTitle;
}
public void setBlogTitle(String blogTitle) {
this.blogTitle = blogTitle;
}
public String getBlogContent() {
return blogContent;
}
public void setBlogContent(String blogContent) {
this.blogContent = blogContent;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getKeywords() {
return keywords;
}
public void setKeywords(String keywords) {
this.keywords = keywords;
}
@Override
public String toString() {
return "BlogCore{" +
"blogId='" + blogId + '\'' +
", blogTitle='" + blogTitle + '\'' +
", blogContent='" + blogContent + '\'' +
", createTime=" + createTime +
", keywords='" + keywords + '\'' +
'}';
}
}
BlogSolrDao.java
package top.yuyufeng.learn.lucene.solr.dao;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import top.yuyufeng.learn.lucene.solr.SolrServer;
import top.yuyufeng.learn.lucene.solr.core.BlogCore;
import java.awt.print.Pageable;
import java.util.List;
import java.util.Map;
/**
* @author yuyufeng
* @date 2017/12/6
*/
public class BlogSolrDao{
HttpSolrClient server;
public BlogSolrDao() {
server = SolrServer.getServer();
}
/**
* 按Bean 添加/修改 索引
*
* @throws Exception
*/
public int addIndex(BlogCore entity) throws Exception {
server.addBean(entity);
UpdateResponse updateResponse = server.commit();
return updateResponse.getStatus();
}
/**
* 按Bean 添加/修改 索引
*
* @throws Exception
*/
public int addIndexList(List<BlogCore> entitys) throws Exception {
server.addBeans(entitys);
UpdateResponse updateResponse = server.commit();
return updateResponse.getStatus();
}
/**
* 刪除索引 按查詢(xún)
*
* @throws Exception
*/
public int deleteAll() throws Exception {
String query = "*:*";
server.deleteByQuery(query);
server.commit();
UpdateResponse updateResponse = server.commit();
return updateResponse.getStatus();
}
/**
* 刪除索引 按id
*
* @throws Exception
*/
public int deleteByQuery(Long id) throws Exception {
server.deleteById(id + "");
server.commit();
UpdateResponse updateResponse = server.commit();
return updateResponse.getStatus();
}
//查詢(xún)所有
public List<BlogCore> query() throws Exception {
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.setStart(0);//開(kāi)始記錄數(shù)
query.setRows(10000);//總條數(shù)
QueryResponse queryResponse = server.query(query);
List<BlogCore> results = queryResponse.getBeans(BlogCore.class);
return results;
}
//搜索keywords
public List<BlogCore> queryByKeyWords(String keywords) throws Exception {
SolrQuery query = new SolrQuery();
query.set("q", "keywords:" + keywords);//*通配多個(gè)字符
// query.set("sort", "product_price desc");
//======高亮設(shè)置===
//開(kāi)啟高亮
query.setHighlight(true);
//高亮域
query.addHighlightField("blogContent");
query.addHighlightField("blogTitle");
//前綴
query.setHighlightSimplePre("<B>");
//后綴
query.setHighlightSimplePost("</B>");
//query.setHighlightSnippets(1);//結(jié)果分片數(shù)袁滥,默認(rèn)為1
//query.setHighlightFragsize(1000);//每個(gè)分片的最大長(zhǎng)度盖桥,默認(rèn)為100
query.setStart(0);//開(kāi)始記錄數(shù)
query.setRows(100);//總條數(shù)
QueryResponse queryResponse = server.query(query);
long sum = queryResponse.getResults().getNumFound();
List<BlogCore> results = queryResponse.getBeans(BlogCore.class);
//輸出高亮
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
for (BlogCore result : results) {
Map<String, List<String>> map = highlighting.get(result.getBlogId()+"");
List<String> list = map.get("blogTitle");
if (list != null && list.size() > 0) {
result.setBlogTitle(list.get(0));
}
list = map.get("blogContent");
if (list != null && list.size() > 0) {
result.setBlogContent(list.get(0));
}
}
return results;
}
}
SolrTest.java
package top.yuyufeng.learn.lucene.solr;
import org.junit.Test;
import top.yuyufeng.learn.lucene.solr.core.BlogCore;
import top.yuyufeng.learn.lucene.solr.dao.BlogSolrDao;
import java.util.Date;
import java.util.List;
/**
* @author yuyufeng
* @date 2017/12/6
*/
public class SolrTest {
@Test
public void testIndex() throws Exception {
BlogSolrDao blogSolrDao = new BlogSolrDao();
BlogCore blog = new BlogCore();
blog.setBlogId("2");
blog.setBlogTitle("達(dá)摩院超越業(yè)界龍頭");
blog.setBlogContent("達(dá)摩院一定也必須要超越英特爾,必須超越微軟题翻,必須超越IBM揩徊,因?yàn)槲覀兩诙皇兰o(jì),我們是有機(jī)會(huì)后發(fā)優(yōu)勢(shì)的。");
blog.setCreateTime(new Date());
blogSolrDao.addIndex(blog);
}
@Test
public void testFindAll() throws Exception {
BlogSolrDao blogSolrDao = new BlogSolrDao();
List<BlogCore> list = blogSolrDao.query();
for (BlogCore blogCore : list) {
System.out.println(blogCore);
}
}
@Test
public void testSearch() throws Exception {
BlogSolrDao blogSolrDao = new BlogSolrDao();
List<BlogCore> list = blogSolrDao.queryByKeyWords("達(dá)摩院");
for (BlogCore blogCore : list) {
System.out.println(blogCore);
}
}
}
運(yùn)行結(jié)果:
啟動(dòng)Solr服務(wù)器后塑荒,我建立了一些索引熄赡,然后我執(zhí)行Search方法
BlogCore{blogId='2', blogTitle='<B>達(dá)摩</B><B>院</B>超越業(yè)界龍頭', blogContent='<B>達(dá)摩</B><B>院</B>一定也必須要超越英特爾,必須超越微軟齿税,必須超越IBM彼硫,因?yàn)槲覀兩诙皇兰o(jì),我們是有機(jī)會(huì)后發(fā)優(yōu)勢(shì)的凌箕。', createTime=Wed Dec 06 13:38:12 CST 2017, keywords='null'}
BlogCore{blogId='1', blogTitle='馬云表達(dá)愿景', blogContent='10月11日杭州云棲大會(huì)上拧篮,馬云表達(dá)了對(duì)新建成的阿里巴巴全球研究<B>院</B>—阿里巴巴<B>達(dá)摩</B><B>院</B>的愿景,希望<B>達(dá)摩</B><B>院</B>二十年內(nèi)成為世界第一大經(jīng)濟(jì)體牵舱,服務(wù)世界二十億人串绩,創(chuàng)造一億個(gè)工作崗位。', createTime=Wed Dec 06 12:03:56 CST 2017, keywords='null'}