<返回更多

开发人员如何快速定制化实现一个基于Solr的搜索引擎

2021-04-02  搜狐网  攻城狮Chova
加入收藏

Solr实现全文搜索

 

Solr

Apache Solr特点

Solr是Lucene的JAVA API包装,使用Solr,就可以使用Lucene的所有功能

搜索引擎

搜索引擎组件

搜索引擎有三个组件:

搜索引擎工作流程

分词技术

 

中文分词算法

基于字符串匹配

基于统计及机器学习的分词方式

IKAnalyzer

部署Solr并安装IKAnalyzer

/usr/local/docker/solr 用于存放docker-compose.yml配置文件

/usr/local/docker/solr/ikanalyzer 用于存放Dockerfile镜像配置文件

version: '3.1'

services:

solr:

build: ikanalyzer

restart: always

container_name: solr

ports:

- 8983:8983

volumes:

- ./solrdata:/opt/solrdata

FROM solr

# 创建Core

WORKDIR /opt/solr/server/solr

RUN mkdir ik_core

WORKDIR /opt/solr/server/solr/ik_core

RUN echo 'name=ik_core' > core.properties

RUN mkdir data

RUN cp -r ../configsets/sample_techproducts_configs/conf/ .

# 安装中文分词

WORKDIR /opt/solr/server/solr-webApp/webapp/WEB-INF/lib

ADD ik-analyzer-solr5-5.x.jar .

ADD solr-analyzer-ik-5.1.0.jar .

WORKDIR /opt/solr/server/solr-webapp/webapp/WEB-INF

ADD ext.dic .

ADD stopword.dic .

ADD IKAnalyzer.cfg.xml .

# 增加分词配置

COPY managed-schema /opt/solr/server/solr/ik_core/conf

WORKDIR /opt/solr

docker-compose up -d

 

Solr分析功能

修改managed-schema配置业务系统字段

<!-- 字段域 -->

<field name="tb_item_cid" type="plong" indexed="true" stored="true" />

<field name="tb_item_cname" type="text_ik" indexed="true" stored="true" />

<field name="tb_item_title" type="text_ik" indexed="true" stored="true" />

<field name="tb_item_sell_point" type="text_ik" indexed="true" stored="true" />

<field name="tb_item_desc" type="text_ik" indexed="true" stored="true" />

<!-- 复制域:Solr的搜索优化功能,,将多个字段复制到一个域,提高查询效率 -->

<field name="tb_item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true" />

<copyField source="tb_item_cname" dest="tb_item_keywords">

<copyField source="tb_item_title" dest="tb_item_keywords">

<copyField source="tb_item_sell_point" dest="tb_item_keywords">

<copyField source="tb_item_desc" dest="tb_item_keywords">

复制配置到容器

docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf

重启容器

docker-compose restart

SpringBoot整合Solr

创建搜索服务接口

<?xml version="1.0" encoding="UTF-8"?>

<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>

<parent>

<groupId>com.funtl</groupId>

<artifactId>myshop-dependencies</artifactId>

<version>1.0.0-SNAPSHOT</version>

<relativePath>../myshop-dependencies/pom.xml</relativePath>

</parent>

<artifactId>myshop-service-search-api</artifacteId>

<packaging>jar<packaging>

</project>

package com.oxford.myshop.service.search.api;

public interface SearchService {

List<TbItemResult> search(String query,int page,int rows);

}

package com.oxford.myshop.service.search.domain;

import java.io.Serializable;

public class TbItemResult implements Serializable {

private long id;

private long tbTtemCid;

private String tbItemCname;

private String tbItemTitle;

private String tbItemSellPoint;

private String tbItemDesc;

public long getId(){

return id;

}

public void setId(long id){

this.id=id;

}

public long getTbTtemCid(){

return tbTtemCid;

}

public void setTbTtemCid(long tbTtemCid){

this.tbTtemCid=tbTtemCid;

}

public String getTbItemCname(){

return tbItemCname;

}

public void setTbItemCname(String tbItemCname){

this.tbItemCname=tbItemCname;

}

public String getTbItemTitle(){

return tbItemTitle;

}

public void setTbItemTitle(String tbItemTitle){

this.tbItemTitle=tbItemTitle;

}

public String getTbItemSellPoint(){

return tbItemSellPoint;

}

public void setTbItemSellPoint(String tbItemSellPoint){

this.tbItemSellPoint=tbItemSellPoint;

}

public String getTbItemDesc(){

return tbItemDesc;

}

public void setTbItemDesc(String tbItemDesc){

this.tbItemDesc=tbItemDesc;

}

}

创建搜索服务提供者

package com.oxford.myshop.service.search.provider;

@EnableHystrix

@EnableHystrixDashboard

@SpringBootApplication(scanBasePackages="com.oxfrod.myshop")

@MapperScan(basePackages="com.oxford.myshop.service.search.provider.mapper")

public class MyShopServiceSearchProviderApplication {

public static void main(String[] args) {

SpringApplication.run(MyShopServiceSearchProviderApplication.class,args);

Main.main(args);

}

}

package com.oxford.myshop.service.search.provider.mapper;

@Respository

public interface TbItemResultMapper {

List<TbItemResult> selectAll();

}

Spring的四大注解:

1. @Controller

2. @Service

3. @Component

4. @Repository

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.oxford.myshop.service.search.provider.mapper.TbItemResultMapper">

<resultMap id="BaseResultMap" type="com.oxford.myshop.service.search.domainTbItemResult">

<id column="id" jdbcType="BIGINT" property="id" />

<result column="tb_item_cid" jdbcType="BIGINT" property="tbItemCid" />

<result column="tb_item_cname" jdbcType="VARCHAR" property="tbItemCname" />

<result column="tb_item_title" jdbcType="VARCHAR" property="tbItemTitle" />

<result column="tb_item_sell_point" jdbcType="VARCHAR" property="tbItemSellPoint" />

<result column="tb_item_desc" jdbcType="VARCHAR" property="tbItemDesc" />

</reslutMap>

<select id="selectAll" resultMap="BaseResultMap">

select

a.id,

a.title as tb_item_title,

a.sell_point as tb_item_sell_point,

a.cid as tb_item_cid,

b.name as tb_item_cname,

c.item_desc as tb_item_desc

from

tb_item as a

left join tb_item_cat as b

on a.cid=b.id

left join tb_item_desc as c

on a.id=c.item_id

</select>

</mapper>

初始化Solr:

public void initSolr() {

List<TbItemResult> tbItemResult=tbItemResultMapper.selectAll();

try{

SolrInputDocument document=null;

for(TbItemResult tbItemResult:tbItemResults){

document=new SolrInputDocument();

document.addFiled("id",tbItemResult.getId());

document.addFiled("tb_item_cid",tbItemResult.getTbItemCid());

document.addFiled("tb_item_cname",tbItemResult.getTbItemCname());

document.addFiled("tb_item_title",tbItemResult.getTbItemTitle());

document.addFiled("tb_item_sell_point",tbItemResult.getTbItemSellPoint());

document.addFiled("tb_item_desc",tbItemResult.getTbItemDesc());

solrClient.add(document);

solrClient.commit();

}

}catch(SolrServerException e){

e.printStackTrace();

}catch(IOException e){

e.printStackTrace();

}

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

搜索Solr:

public void searchSolr(){

SolrQuery query=new SolrQuery();

// 设置查询条件

query.setQuery("手机");

// 分页查询

query.setStart(0);

query.setRows(10);

// 设置查询的默认域

query.set("df","tb_item_keywords");

// 设置高亮显示

query.setHighlight(true);

query.addHighlightField("tb_item_title");

query.setHighlightSimplePre("<span style='color:red;'>");

query.setHighlightSimplePost("</span>");

// 开始查询

try{

QueryResponse queryResponse=solrClient.query(query);

SolrDocumentList results=queryResponse.getResults();

// 获取高亮

Map<String,Map<String,List<String>>> highlighting=queryResponse.getHighlighting();

for(SolrDocument result:results){

List<String> strings=highlighting.get(result.get("id")).get(result.get("tb_item_title"))

if(strings!=null&&strings.size()>0){

String title=strings.get(0);

System.out.println(title);

}

}

}catch(SolrServerException e){

e.printStackTrace();

}catch(IOException e){

e.printStackTrace();

}

}

package com.oxford.myshop.service.search.provider.api.impl;

@Service(version="${services.versions.search.v1}")

public class SearchServiceImpl implements SearchService{

@Autowired

private SolrClient solrClient;

@Override

public List<TbItemResult> search(String query,int page,int rows){

List<TbItemResult> searchResults=Lists.newArrayList();

SolrQuery query=new SolrQuery();

// 设置查询条件

query.setQuery("手机");

// 分页查询

query.setStart((page-1)*rows);

query.setRows(rows);

// 设置查询的默认域

query.set("df","tb_item_keywords");

// 设置高亮显示

query.setHighlight(true);

query.addHighlightField("tb_item_title");

query.setHighlightSimplePre("<span style='color:red;'>");

query.setHighlightSimplePost("</span>");

// 开始查询

try{

QueryResponse queryResponse=solrClient.query(query);

SolrDocumentList results=queryResponse.getResults();

// 获取高亮

Map<String,Map<String,List<String>>> highlighting=queryResponse.getHighlighting();

for(SolrDocument solrDocument:solrDocuments){

TbItemResult result=new TbResult();

result.setId(Long.parseLong(String.valueOf(solrDocument.get("id"))));

result.setTbItemCid(Long.parseLong(String.valueOf(solrDocument.get("tb_item_cid"))));

result.setTbItemCname((String)solrDocument.get("tb_item_cname"));

result.setTbItemTitle((String)solrDocument.get("tb_item_title"));

result.setTbItemSellPoint((String)solrDocument.get("tb_item_sell_point"));

result.setTbItemDesc((String)solrDocument.get("tb_item_desc"));

String tbItemTitle="";

List<String> list=highlighting.get(result.get("id")).get(result.get("tb_item_title"))

if(list!=null&&lsit.size()>0){

String title=list.get(0);

}else{

tbItemTitle=(String)solrDocument.get("tb_item_title");

}

result.setTbItemTitle(tbItemTitle);

searchResults.add(result);

}

}catch(SolrServerException e){

e.printStackTrace();

}catch(IOException e){

e.printStackTrace();

}

return searchResults;

}

}

创建搜索服务消费者

package com.oxford.myshop.service.search.consumer;

@EnableHystrix

@EnableHystrixDashboard

@SpringBootApplication(scanBasePackages="com.oxford.myshop",exclude=DataSourceAutoConfiguration.class)

public class MyShopServiceSearchConsumerApplication{

public static void main(String[] args){

SpringApplication.run(MyShopServiceSearchConsumerApplication.class,args);

Main.main(args);

}

}

package com.oxford.myshop.service.search.consumer.controller;

@RestController

public class SearchController{

@Reference(version="${services.versions.search.v1}")

private SearchService searchService;

@RequestMapping(value="search/{query}/{page}/{rows}",method=RequestMethod.GET)

public List<TbItemResult> search(

@PathVariable(required=true) String query,

@PathVariable(required=true) int page,

@PathVariable(required=true) int rows

){

return searchService.search(query,page,rows)

}

}

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>