问答媒体

 找回密码
 立即注册
快捷导航
搜索
热搜: 活动 交友 discuz
查看: 95|回复: 2

Solr

[复制链接]

3

主题

6

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2022-12-28 14:59:27 | 显示全部楼层 |阅读模式
1.Solr的概述:

Solr是一个高性能,采用Java开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。
主要特点:全文搜索、高亮、分面搜索、实时索引、动态类聚、数据库集成、NoSQL特性和丰富的文档处理。
<hr/>2.Solr+ikanalyzer的配置和安装

基于docker-compose + Dockerfile的配置和安装:
需要准备一下文件
docker-compose.yml
ikanalyzer  #文件夹
      ext.dic
      IKAnalyzer.cfg.xml
      ik-analyzer-solr5-5.x.jar
      managed-schema     //注册字段的配置文件
      solr-analyzer-ik-5.1.0.jar    //中文分词工具包
      stopword.dic
      Dockerfile     //自定义镜像docker-compose.yml
version: '3.1'
services:
  solr:
    build: ikanalyzer #构建的文件夹
    restart: always
    container_name: solr  #容器名
    ports:
      - 8983:8983
    volumes:
      - ./solrdata:/opt/solrdata  #数据卷绑定Dockerfile
#自定义镜像
FROM solr:7.1.0

# 创建 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<hr/>3.Solr插入数据

3.1 注册字段

插入数据前先设计好数据模型,然后在存到Solr中                                                            注意:在solr中添加数据,必须先在managed-schema文件中注册(shift+g 快速定位到文件底部),被注册过的字段就可以进行分词,这样数据就可以被查询
# 字段域(text_ik:支持中文分词   type="pfloat":字段类型  indexed="true":支持索引)
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_price" type="pfloat" indexed="true" stored="true"/>
<field name="product_pimage" type="text_general" indexed="true" stored="true"/>
<field name="product_pdesc" type="text_ik" indexed="true" stored="true"/>

# 复制域(Solr 的搜索优化功能,将多个字段域复制到一个域里,提高查询效率)
<field name="product_name_pdesc" type="text_ik" indexed="true" stored="false" multiValued="true"/>
   <copyField source="product_name" dest="product_name_pdesc"/>
   <copyField source="product_pdesc" dest="product_name_pdesc"/>注册完字段必须要将配置文件复制到容器,不是实时更新,或者选择删除镜像重新构建
# 复制到容器
docker cp managed-schema solr:/opt/solr/server/solr/ik_core/conf

# 重启容器
docker-compose restart3.2 web中添加数据

# 下面的字段必须在solr 中注册过才可以使用
{
    id: "1",
    product_name: "小米9 Pro",
    product_price: 3999,
    product_pdesc: "小米9 Pro 不仅是一部超快的 5G 手机,更是一部全面成熟的性能旗舰"
}


添加数据

3.3 web中查询数据




查询数据

3.4 web中删除数据




删除数据

<hr/>4.Java操作Solr

添加依赖
spring:
  data:
    solr:
      host: http://192.168.88.88:8983/solr/ik_core
编写配置文件
<!--solr核心依赖-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>4.1 查询数据
/**
     * 简单查询
     * 1.先设置查询参数==>封装一个SolrQuery对象
     * 2.提交给solrClient执行查询并得到结果集
     * 3. 解析结果集
     */
    @Autowired
    SolrClient solrClient;

    @Test
    void testSimpleQuery() throws IOException, SolrServerException {

        SolrQuery query = new SolrQuery();
        String keyword = "手机";
        query.setQuery(keyword);
        query.set("df","product_name_pdesc");
        query.setStart(0);
        query.setRows(10);

        QueryResponse response = solrClient.query(query);
        SolrDocumentList results = response.getResults();

        List<Product> products = new ArrayList<>();

        for (SolrDocument result : results) {

            Long id = Long.valueOf((String)result.getFieldValue("id"));
            String product_name = (String) result.getFieldValue("product_name");
            Float product_price = (Float)result.getFieldValue("product_price");
            String product_pdesc = (String) result.getFieldValue("product_pdesc");
      
            Product product = new Product();
            //将从solr中查询到的数据封装到JavaBean中
            product.setId(id);
            product.setProduct_name(product_name);
            product.setProduct_pdesc(product_pdesc);
            product.setProduct_price(new BigDecimal(product_price));

            products.add(product);
        }

        System.out.println(products);

    }4.2 添加数据
/***
* 从数据库中检索出数据,将数据插入到solr库中
*/
@Autowired
SolrClient solrClient;

@Test
void TestInsertDataToSolr(){
    List<Product> products = productSearchMapper.selectAll();

    System.out.println(products);

    //遍历products集合,江北一个product对象封装成一个SolrInputDocument对象
    //再把对象添加到集合中
    //将该集合添加到solr库中
    List<SolrInputDocument> docs= new ArrayList<>();

    for (Product product : products) {
       SolrInputDocument doc = new SolrInputDocument();
       doc.setField("id",product.getId());
       doc.setField("product_name",product.getProduct_name());
       doc.setField("product_price",product.getProduct_price().floatValue());
       doc.setField("product_pdesc",product.getProduct_pdesc());
       docs.add(doc);
     }
     try {
       solrClient.add(docs);
       solrClient.commit();
    } catch (SolrServerException e) {
       e.printStackTrace();
    } catch (IOException e) {
       e.printStackTrace();
    }
}4.3 高亮查询
@Autowired
SolrClient solrClient;
@Test
void testHightLight() throws IOException, SolrServerException {

    SolrQuery query = new SolrQuery();

    //设置查询参数
    String keyword = "小米";
    query.setQuery(keyword);
    query.set("df","product_name_pdesc");
    query.setStart(0);
    query.setRows(10);

    //高亮
    query.setHighlight(true);
    query.addHighlightField("product_name");
    query.setHighlightSimplePre("<span style='color:green'>");
    query.setHighlightSimplePost("</span>");

    //执行查询,得到结果集
    QueryResponse response = solrClient.query(query);
    List<Product> products = new ArrayList<>();
    SolrDocumentList results = response.getResults();
    Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();

    for (SolrDocument result : results) {

        Product product = new Product();
        String id_str = (String) result.getFieldValue("id");
        Long id = Long.valueOf(id_str);
        product.setId(id);

        //高亮的商品名称的封装
        Map<String, List<String>> stringListMap = highlighting.get(id_str);
        List<String> product_names = stringListMap.get("product_name");
        System.out.println(product_names);
        String product_nameHl = product_names.get(0);
        product.setProduct_name(product_nameHl);
        //高亮end

        Float product_price = (Float)result.getFieldValue("product_price");
        product.setProduct_price(new BigDecimal(product_price));
        String  product_pdesc = (String)result.getFieldValue("product_pdesc");
        product.setProduct_pdesc(product_pdesc);
        products.add(product);
    }

    System.out.println(products);


}
<hr/>2020年2月26日02:01:39
回复

使用道具 举报

1

主题

11

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2025-5-6 14:44:21 | 显示全部楼层
我也是坐沙发的
回复

使用道具 举报

1

主题

6

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2025-5-6 22:48:41 | 显示全部楼层
为保住菊花,这个一定得回复!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver| 手机版| 小黑屋| 问答媒体

GMT+8, 2025-7-17 07:57 , Processed in 0.104629 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2020, LianLian.

快速回复 返回顶部 返回列表