1. 程式人生 > >搜尋引擎solr(六)--使用spring data 操作solr

搜尋引擎solr(六)--使用spring data 操作solr

一、簡介

前面有介紹通過solr的java客戶端操作solr,這裡介紹另一種操作solr的方式,使用spring data操作

solr,進行資料的增刪改查操作。

這裡使用的solr版本是7.2.0,由於最新版本的spring-data(3.0.7.RELEASE)僅支援solr的java客戶端版本6.6.1,因

此這使用solr的java客戶端版本為6.6.1,spring的版本為5.0.4.RELEASE。

二、開發步驟

1、新增maven依賴

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>
solr-solrj</artifactId> <version>6.6.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-solr</artifactId> <version>3.0.7.RELEASE</version> </dependency>

2、定義bean類

import 
org.springframework.data.annotation.Id; import org.springframework.data.solr.core.mapping.Indexed; import org.springframework.data.solr.core.mapping.SolrDocument; import java.io.Serializable; import java.util.Date; @SolrDocument(solrCoreName = "stu") public class Stu implements Serializable { private static final long
serialVersionUID = 566392553987979222L; @Id @Indexed(name = "stu_id") private String stuId; @Indexed(name = "stu_name") private String stuName; @Indexed(name = "create_time") private Date createTime; public Stu() { } public Stu(String stuId, String stuName) { this.stuId = stuId; this.stuName = stuName; } public Stu(String stuId, String stuName, Date createTime) { this.stuId = stuId; this.stuName = stuName; this.createTime = createTime; } public String getStuId() { return stuId; } public void setStuId(String stuId) { this.stuId = stuId; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @Override public String toString() { return "Stu{" + "stuId='" + stuId + '\'' + ", stuName='" + stuName + '\'' + ", createTime=" + createTime + '}'; } }

備註:通過註解@SolrDocument聲明當前bean的core,通過註解@Id確認唯一id,

通過註解@Indexed可重定義欄位屬性(如通過name重定義欄位名稱)

3、定義repository類

import com.dragon.study.solr.bean.Stu;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.result.HighlightPage;
import org.springframework.data.solr.repository.Highlight;
import org.springframework.data.solr.repository.SolrCrudRepository;
public interface StuSolrRepository extends SolrCrudRepository<Stu, String> {

    /**
     * 根據指定屬性查詢,高亮顯示
     * @param stuName
* @param pageable
* @return
*/
@Highlight(prefix = "<b>", postfix = "</b>")
    HighlightPage<Stu> findByStuName(String stuName, Pageable pageable);
/**
     * 分頁模糊查詢
     * @param stuName
* @param pageable
* @return
*/
Page<Stu> findByStuNameLike(String stuName, Pageable pageable);
/**
     * 刪除資料(模糊匹配)
     * @param stuName
*/
void deleteByStuNameLike(String stuName);
}

4、定義spring配置檔案spring-solr.xml

<?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:solr="http://www.springframework.org/schema/data/solr"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/data/solr
    http://www.springframework.org/schema/data/solr/spring-solr.xsd
">
    <solr:solr-client id="solrClient" url="http://192.168.0.107:8983/solr" />
    <solr:repositories base-package="com.dragon.study.solr" />
    <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
        <constructor-arg ref="solrClient" />
    </bean>
</beans>

5、測試

import com.dragon.study.solr.bean.Stu;
import com.dragon.study.solr.repository.StuSolrRepository;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.result.HighlightPage;
import java.util.Date;
import java.util.function.Consumer;
public class SolrSpringMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-solr.xml");
StuSolrRepository stuSolrRepository = ac.getBean(StuSolrRepository.class);
//查詢單個
Stu stu = stuSolrRepository.findById("002").get();
System.out.println(stu);
//工具,輸出結果
Consumer<Stu> consumer = s -> System.out.println(s);
//查詢所有
Iterable<Stu> it = stuSolrRepository.findAll();
it.forEach(consumer);
//分頁查詢所有資料
Pageable pageable = PageRequest.of(0, 3);
Page<Stu> page = stuSolrRepository.findAll(pageable);
System.out.println(page.getContent());
//高亮查詢
HighlightPage<Stu> highlightPage = stuSolrRepository.findByStuName("劉邦", pageable);
System.out.println(highlightPage);
//模糊查詢
Page<Stu> likPage = stuSolrRepository.findByStuNameLike("劉", pageable);
System.out.println(likPage);
//儲存或更新(當唯一id,即stu_id一樣時)資料
//        Stu stu1 = new Stu("008", "小方", new Date());
Stu stu1 = new Stu("009", "小明", new Date());
stuSolrRepository.save(stu1);
//根據唯一id刪除資料
stuSolrRepository.deleteById("008");
//模糊匹配刪除資料
stuSolrRepository.deleteByStuNameLike("小");
ac.close();
}
}

三、附錄

1、下面是從spring data solr官網上摘的reposity各種資料操作對應表格

Table 2. Supported keywords inside method names
KeywordSampleSolr Query String

And

findByNameAndPopularity

q=name:?0 AND popularity:?1

Or

findByNameOrPopularity

q=name:?0 OR popularity:?1

Is

findByName

q=name:?0

Not

findByNameNot

q=-name:?0

IsNull

findByNameIsNull

q=-name:[* TO *]

IsNotNull

findByNameIsNotNull

q=name:[* TO *]

Between

findByPopularityBetween

q=popularity:[?0 TO ?1]

LessThan

findByPopularityLessThan

q=popularity:[* TO ?0}

LessThanEqual

findByPopularityLessThanEqual

q=popularity:[* TO ?0]

GreaterThan

findByPopularityGreaterThan

q=popularity:{?0 TO *]

GreaterThanEqual

findByPopularityGreaterThanEqual

q=popularity:[?0 TO *]

Before

findByLastModifiedBefore

q=last_modified:[* TO ?0}

After

findByLastModifiedAfter

q=last_modified:{?0 TO *]

Like

findByNameLike

q=name:?0*

NotLike

findByNameNotLike

q=-name:?0*

StartingWith

findByNameStartingWith

q=name:?0*

EndingWith

findByNameEndingWith

q=name:*?0

Containing

findByNameContaining

q=name:*?0*

Matches

findByNameMatches

q=name:?0

In

findByNameIn(Collection<String> names)

q=name:(?0…​ )

NotIn

findByNameNotIn(Collection<String> names)

q=-name:(?0…​ )

Within

findByStoreWithin(Point, Distance)

q={!geofilt pt=?0.latitude,?0.longitude sfield=store d=?1}

Near

findByStoreNear(Point, Distance)

q={!bbox pt=?0.latitude,?0.longitude sfield=store d=?1}

Near

findByStoreNear(Box)

q=store[?0.start.latitude,?0.start.longitude TO ?0.end.latitude,?0.end.longitude]

True

findByAvailableTrue

q=inStock:true

False

findByAvailableFalse

q=inStock:false

OrderBy

findByAvailableTrueOrderByNameDesc

q=inStock:true&sort=name desc

2、若執行java程式碼時,出現報錯Document is missing mandatory uniqueKey field: id時,這時說

明managed-schema中的<uniqueKey>id</uniqueKey>與bean中使用@id註解的欄位名稱不一致。

這時應修改managed-schema檔案的唯一標識為<uniqueKey>stu_id</uniqueKey>,同時刪除

<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>