Solr
概念:
1. 搜索引擎的技術,建立在Lucene之上,可以解決跨平台,跨語言的問題.(Lucene本身是個jar包,也就是API,不能獨立運行,需要程序的調用來完成全局檢索,不具備跨平台,跨語言).
2. 基於Lucene的全文檢索服務,是可以獨立運行的(war包,運行在tomcat).
solr安裝
1. 解壓新的tomcat
2. 將solr進行解壓
3. 找到solr.war:
* D:\develop\lucene\solr\solr-4.10.3\dist 下,自己的解壓目錄
* D:\develop\lucene\solr\solr-4.10.3\example\webapps 下也有
4. 將war包放在tomcat的webapps下
5. 啟動tomcat,解壓war包,關閉tomcat
6. 將D:\develop\lucene\solr\solr-4.10.3\example下有個solr文件夾,將該文件夾拷貝到D盤根目錄(習慣)
* solrHome: 是solr運行的主目錄
* solrCore: 類似於數據庫,可以單獨對外提供索引和搜索的服務
* 一個solrHome下包含多個solrCore
7. 在tomcat的webapps下的solr的解壓文件夾下的WEB-INF下的web.xml,進行修改:
第41到45行(修改<env-entry-value>的目錄為第六步復制后的那個目錄):
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>D:\solr</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
8. 復制擴展包:
D:\develop\lucene\solr\solr-4.10.3\example\lib\ext目錄下的所有包復制到tomcat的webapps下的solr下的WEB-INF下的lib下,然后可以啟動tomcat,在網頁進行訪問 localhost:8080/solr
中文分析器IK Analyzer
1. 為什么要使用IK呢?
因為solr是由外國人研發,對漢語的分詞是一個漢字一個漢字分的,所以引入IK,對中文有很好的分詞效果,並且可以自定義擴充分詞詞典
2. 安裝IK
1. 解壓IK Analyzer 2012FF_hf1.zip
2. 將解壓目錄下的IKAnalyzer2012FF_u1.jar放在tomcat下的webapps下的solr下的WEB-INF下的lib下
3. 拷貝解壓目錄下的IKAnalyzer.cfg.xml,ext_stopword.dic,mydict.dic放在tomcat下的webapps下的solr下的WEB-INF下的classes下,classes不存在創建一個就好
4. 到前面安裝solr時的那個solrhome下,修改collection1\conf\schema.xml,在1152行添加:
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
5. 選擇分詞的時候選擇text_ik,就可以使用中文分析器了.(筆者第一次就是選擇text,一直失敗,謹此注意一下)
配置域:
1. 域是針對當前項目而言的
* 需要根據什么樣的條件進行查詢
* 查詢出來的記過需要展示的數據信息
* 需要用到的字段
2. 使用solr進行索引創建,所指定的域 必須在schema.xml中存在,否則會創建失敗.
3. 關於域的屬性:
* name: 所指定域的名稱
* type: 域的類型-----> 引用filedType中的name屬性(是否分詞)---->為了索引
* indexed: 是否索引----> 為了搜索
* stored: 是否存儲----> 為了展示
* required: 是否必須
* multiValued: 是否多值
4. 針對本項目,修改schema.xml文件,在</schema>之前添加:
<field name="item_goodsid" type="long" indexed="true" stored="true"/>
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="double" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category" type="string" indexed="true" stored="true" />
<field name="item_seller" type="text_ik" indexed="true" stored="true" />
<field name="item_brand" type="string" indexed="true" stored="true" />
5. 復制域(多個字段進行搜索):
<field name="item_keywords" type="text_ik" indexed="true" stored="false"
multiValued="true"/>
6. 動態域(通配)
7. 主鍵:
SolrJ(原理: http請求和響應)
Solr官方提供的API(理解)
SpringDataSolr(對SolrJ的封裝)
1. 引入依賴:
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
2. 基本的操作:
package springdatasolr;
import com.wzlove.pojo.TbItem;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName SpringDataSolrDemo
* @Author wz157
* @Date 2018/11/8 15:22
* @Description TODO
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext-solr.xml"})
public class SpringDataSolrDemo {
// 注入SolrTemplate
@Autowired
private SolrTemplate solrTemplate;
/**
* 測試添加索引
*/
@Test
public void testAdd(){
TbItem item = new TbItem();
item.setId(1L);
item.setBrand("華為");
item.setCategory("手機");
item.setGoodsId(1L);
item.setSeller("華為2號專賣店");
item.setTitle("華為 Mate9");
item.setPrice(new BigDecimal(2000));
solrTemplate.saveBean(item);
solrTemplate.commit();
}
/**
* 根據主鍵進行查詢,getById()
*/
@Test
public void findByUniqueKey(){
TbItem byId = solrTemplate.getById(1, TbItem.class);
System.out.println(byId);
}
/**
* 根據主鍵進行刪除,deleteById() 記得傳字節碼文件
*/
@Test
public void deleteByUniqueKey(){
solrTemplate.deleteById("1");
// 提交
solrTemplate.commit();
}
/**
* 批量插入,saveBeans
*/
@Test
public void testAddList(){
List<TbItem> list = new ArrayList<TbItem>(100);
for (int i = 0; i < 100; i++) {
TbItem item = new TbItem();
item.setId(i + 1L);
item.setBrand("華為" + i);
item.setCategory("手機");
item.setGoodsId(1L);
item.setSeller("華為2號專賣店" + i);
item.setTitle("華為 Mate9" + i );
item.setPrice(new BigDecimal(2000 + i));
list.add(item);
}
solrTemplate.saveBeans(list);
solrTemplate.commit();
}
/**
* 分頁查詢(總頁數,總記錄數)
* offset 開始索引
* rows 每頁記錄數
*/
@Test
public void testQueryByPage(){
// 創建查詢條件,查詢所有使用 *:*
Query query = new SimpleQuery("*:*");
// 設置分頁條件
query.setOffset(2);
query.setRows(5);
// 執行分頁查詢
ScoredPage<TbItem> tbItems = solrTemplate.queryForPage(query, TbItem.class);
// 解析分頁結果
for (TbItem tbItem : tbItems) {
System.out.println(tbItem.getBrand());
System.out.println(tbItem.getPrice());
}
System.out.println("總記錄的數 : " + tbItems.getTotalElements());
System.out.println("總頁數 : " + tbItems.getTotalPages());
}
/**
* 條件查詢
*/
@Test
public void testPageQueryMutil(){
// 創建查詢條件,查詢所有使用 *:*
Query query = new SimpleQuery("*:*");
// 設置查詢條件(Criterial)
Criteria criteria = new Criteria("item_brand").contains("2");
criteria = criteria.and("item_seller").contains("2");
query.addCriteria(criteria);
// 執行分頁查詢
ScoredPage<TbItem> tbItems = solrTemplate.queryForPage(query, TbItem.class);
// 解析分頁結果
for (TbItem tbItem : tbItems) {
System.out.println(tbItem.getBrand() + " " + tbItem.getPrice() + " " + tbItem.getSeller());
}
System.out.println("總記錄的數 : " + tbItems.getTotalElements());
System.out.println("總頁數 : " + tbItems.getTotalPages());
}
/**
* 全部刪除
*/
@Test
public void testDeleteAll(){
Query query = new SimpleQuery("*:*");
solrTemplate.delete(query);
solrTemplate.commit();
}
}
3. 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:solr="http://www.springframework.org/schema/data/solr"
xsi:schemaLocation="http://www.springframework.org/schema/data/solr
http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- solr 服務器地址,相當於配置了HttpSolrServer這個bean -->
<solr:solr-server id="solrServer" url="http://127.0.0.1:8080/solr/collection1" />
<!-- solr 模板,使用 solr 模板可對索引庫進行 CRUD 的操作 -->
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer" />
</bean>
</beans>
4. 實體:
public class TbItem implements Serializable {
@Field
private Long id;
@Field("item_title")
private String title;
@Field("item_price")
private BigDecimal price;
@Field("item_image")
private String image;
@Field("item_goodsid")
private Long goodsId;
@Field("item_category")
private String category;
@Field("item_brand")
private String brand;
@Field("item_seller")
private String seller;
get和set
@Override
public String toString() {
return "TbItem{" +
"id=" + id +
", title='" + title + '\'' +
", sellPoint='" + sellPoint + '\'' +
", price=" + price +
", stockCount=" + stockCount +
", num=" + num +
", barcode='" + barcode + '\'' +
", image='" + image + '\'' +
", categoryid=" + categoryid +
", status='" + status + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", itemSn='" + itemSn + '\'' +
", costPirce=" + costPirce +
", marketPrice=" + marketPrice +
", isDefault='" + isDefault + '\'' +
", goodsId=" + goodsId +
", sellerId='" + sellerId + '\'' +
", cartThumbnail='" + cartThumbnail + '\'' +
", category='" + category + '\'' +
", brand='" + brand + '\'' +
", spec='" + spec + '\'' +
", seller='" + seller + '\'' +
'}';
}
}
5. 需要注意的是在solr庫的schema約束中配置域