solr極速搜尋
一 。solr簡介
solr是以lucene為核心開發的企業級搜尋應用 應用程式可以通過http請求方式來提交索引,查詢索引,提供了比lucene更豐富的查詢語言,是
一個高效能,高可用環境全文搜尋引擎
二 。solr安裝配置
1》下載solr安裝包 solr所有版本 (http://archive.apache.org/dist/lucene/solr/) 這裡下載 solr-5.5.5 2》安裝 解壓將solr-5.5.5\server\solr-webapp下的webapp 拷貝到tomcat\webapps目錄下 改名為solr 啟動tomcat 直接訪問 出現404 找到tomcat/logs/localhost.2017-08-17.log 日誌 出現以下異常
java.lang.NoClassDefFoundError: Failed to initialize Apache Solr: Could not find necessary SLF4j logging jars.
If using Jetty, the SLF4j logging jars need to go in the jetty lib/ext directory. For other containers,
the corresponding directory should be used. For more information, see: http://wiki.apache.org/solr/SolrLogging at org.apache.solr.servlet.CheckLoggingConfiguration.check(CheckLoggingConfiguration.java:27)
at org.apache.solr.servlet.BaseSolrFilter.<clinit>(BaseSolrFilter.java:30)
可用看到缺少SLF4j包 應該去 應該去 解壓包 /server/lib/ext下找到並拷貝到 tomcat/solr/lib目錄下 然後重啟
繼續訪問 出現以下錯誤
java.lang.NoSuchMethodError: javax.servlet.ServletInputStream.isFinished()Z
org.apache.solr.servlet.SolrDispatchFilter.consumeInputFully(SolrDispatchFilter.java:284)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:274)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:208)
明顯是Servlet版本不一致 tomcat6不支援solr5.54 加大tomcat版本 tomcat7也不支援 換成tomcat8 啟動後訪問 依然錯誤:
org.apache.solr.common.SolrException: Error processing the request. CoreContainer is either not initialized or shutting down.
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:217)
org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:208)
因為需要配置solrhome和solrhome的配置環境
3》配置solrhome
找到 tomcat\solr\WEB-INF\web.xml 編輯 找到以下這段(配置solrhome) 去掉註釋 將第二個引數配置為本地任意一個目錄即可
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>D:\learn\solr-5.5.4\home</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
找到solr解壓包/server/solr目錄拷貝所有檔案到 以上web.xml指定的路徑
D:\learn\solr-5.5.5\home下 重啟tomcat 訪問
http://localhost:8080/solor/index.html 或者 http://localhost:8080/solr/admin.html
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>cn.ps</groupId>
<artifactId>Solr</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency> <!-- 分詞器,附帶引入下面三個jar,版本為4.7.2不支援中文分詞,此處需要5.5.5故需單獨引入下列包-->
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.5.5</version>
</dependency>
</dependencies>
</project>
4》修改原始碼,因為ik 2012年停止更新,僅支援4.7,此處需要5.5.5版本,故需修改原始碼,同包,同類,同方法,會覆蓋,呼叫時優先呼叫專案自己定義的
新建包與jar包該類一致的名字,並拷貝這兩個類
修改IKAnalyzer類此方法
@Override
protected TokenStreamComponents createComponents(String fieldName, final Reader in) {
Tokenizer _IKTokenizer = new IKTokenizer(in, this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
修改為下圖方法內容
@Override
protected TokenStreamComponents createComponents(String fieldName) {
Tokenizer _IKTokenizer = new IKTokenizer( this.useSmart());
return new TokenStreamComponents(_IKTokenizer);
}
修改IKTokenizer
//修改前
public IKTokenizer(Reader in, boolean useSmart) {
super(in);
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
//修改後
public IKTokenizer(boolean useSmart) {
offsetAtt = addAttribute(OffsetAttribute.class);
termAtt = addAttribute(CharTermAttribute.class);
typeAtt = addAttribute(TypeAttribute.class);
_IKImplement = new IKSegmenter(input, useSmart);
}
將這兩個的class檔案替換到jar包中
用壓縮工具開啟jar包ikanalyzer-2012_u6.jar
路徑:ikanalyzer-2012_u6.jar\org\wltea\analyzer\lucene
替換這兩個檔案即可
點選Add core後 成功後 檢查 mycore目錄 發現多了 core.properties和data兩個資源
登陸solr管理網站發現 列表中多了mycore
5 》配置檔案理解
core/conf目錄下的兩個配置檔案非常重要
managed-schema 主要用於配置 可以提交到該core的所有field定義,field的型別定義,唯一識別符號等
常用配置如下:
定義欄位 _version_ 型別為long indexed="true" 會進行分詞索引 stored="true"表示儲存到磁碟
<field name="_version_" type="long" indexed="true" stored="true"/>
定義欄位 id required="true" 表示所有的document必須新增id欄位 multiValued="false" 表示是否是多值欄位
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
定義動態欄位 所以_i結尾的欄位都可以寫入到當前的core
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
定義唯一識別符號的欄位
<uniqueKey>id</uniqueKey>
定義欄位型別的別名
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
solrconfig.xml 主要用於配置solor的主要配置資訊 比如lucene版本 快取 資料目錄 請求路徑對映 等
表示lucene版本
<luceneMatchVersion>5.5.5</luceneMatchVersion>
表示資料目錄 預設是data目錄
<dataDir>${solr.data.dir:}</dataDir>
自動提交配置
<autoCommit>
當超過15000ms後自動提交所有資料
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
是否馬上就可以查詢到
<openSearcher>false</openSearcher>
</autoCommit>
表示當路徑為 /select時查詢所有的資料
<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
will be overridden by parameters in the request
-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
</lst>
</requestHandler>
嘗試在介面上新增資料和查詢資料
新增資料
查詢的引數列表
q表示查詢的條件 欄位名:值的格式 多個條件組合查詢可以使用 欄位:欄位值 && 欄位1:欄位值1 也可以使用大寫的AND或者OR
fq表示filter query 過濾條件 和q是and的關係支援各種邏輯運算子 (參考https://cwiki.apache.org/confluence/display/solr/The+Standard+Query+Parser)
sort表示排序 的欄位 欄位名 asc|desc
start 表示從第幾行開始 rows表示查詢的總行數
fl表示查詢顯示的列 比如只需要查詢 name_s,sex_i 這兩列 使用,隔開
df表示預設的查詢欄位 一般不設定
Raw Query Parameters表示原始查詢欄位 可以使用 start=0&rows=10這種url的方式傳入引數
wt(write type)表示寫入的格式 可以使用json和xml
shards 多核同時搜尋 solrhome拷貝mycore為mycore1 管理平臺新增core 設定引數為 路徑,路徑來設定需要搜尋的核
String shards = “localhost:8080/solr/mycore,localhost:8080/solr/mycore1”;
query.set(“shards”, shards);
其他參考(https://cwiki.apache.org/confluence/display/solr/Common+Query+Parameters)
將solrhome下 配置檔案managed-schema 新增一個欄位型別 使用ik分詞器
<fieldType name="text_ik" class="solr.TextField" >
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
不能修改 StrField 不支援自定義分詞器
<fieldType name="string" class="solr.StrField" sortMissingLast="true" > </fieldType>
然後將對應需要進行中文分詞的欄位使用 text_ik該欄位型別 比如
重啟 或者 cloud環境下重新生成collection 插入資料即可實現中文分詞 通過某些中文關鍵字搜尋建立配置data-conf.xml
<?xml version="1.0" encoding="UTF8"?>
<dataConfig>
<dataSource name="source1" type="JdbcDataSource" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.0.250:3306/school" user="root" password="ps123456" batchSize="-1" />
<document> <!-- 自動匯入要查詢表的資料 -->
<entity name="book" pk="newid" dataSource="source1" query="select * from mytext" >
<field column="newid" name="id"/>
<field column="newtitle" name="title_ik"/>
</entity>
</document>
</dataConfig>
新增到solrconfig.xml,並一同拷貝到mycore1 核的配置目錄
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-conf.xml</str>
</lst>
</requestHandler>
拷回去
docker cp ./data-conf.xml my_solr:/opt/solr/server/solr/mycore1/conf
docker cp ./solrconfig.xml my_solr:/opt/solr/server/solr/mycore1/conf
managed-schema 拷出來,新增如下配置,在拷回去
docker cp my_solr:/opt/solr/server/solr/mycore1/conf/managed-schema ./
改完後拷回去
docker cp ./managed-schema my_solr:/opt/solr/server/solr/mycore1/conf/
<fieldType name="text_ik" class="solr.TextField" >
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<dynamicField name="*_ik" type="text_ik" indexed="true" stored="true"/>
訪問solrweb管理介面 http://ip:
mysql資料
頁面查詢資料
支援資料庫語句,關鍵字必須大寫
java程式碼查詢
控制層
@RestController
public class SolrControll {
@Autowired
private SolrTemplate temp;
@GetMapping("/que")
public List<Entity> news(String keyword) {
SimpleQuery siq=new SimpleQuery("title_ik:"+keyword);
System.out.println(keyword+"------------");
Page<Entity> query=temp.query(siq, Entity.class);
return query.getContent();
}
}
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
</dependencies>
properties
spring.data.solr.host=http://192.168.174.131:8983/solr
server.port=8888
頁面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>什麼鬼頁面</title>
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>
<script type="text/javascript">
function query(){
$.ajax({
url:"que",
dataType:"json",
type:"get",
data:"keyword="+$("#keys").val(),
success:function(r){
$("#mynews").text(JSON.stringify(r));
}
});
}
</script>
</head>
<body>
<div>新聞:<input id="keys" type="text"name="keyword" ></div>
<button onclick="query()">搜尋</button>
<div id="mynews"> </div>
</body>
</html>