Solr的使用以及中文分词

经过测试发现spring-data-solr 和solrj这两个jar 包之间存在着版本冲突,最后使用spring-data-solr 3.0.6
solrj 6.6.3 这两个版本没有冲突测试正常。先把这两个pom依赖给大家。

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

首先自己的solr环境要搭建好。接下来就是解决中文分词的问题。

public String getAnalysis(String sentence) throws IOException, SolrServerException {
        FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
        // 字段名,随便指定一个支持中文分词的字段
        request.addFieldName(ZbZskData.FIELD_KEYWORDS);
        // 字段值,可以为空字符串,但是需要显式指定此参数
        request.setFieldValue("");
        request.setQuery(sentence);

        FieldAnalysisResponse response = null;
        response = request.process(solrTemplate.getSolrClient(), ZbZskData.CORE_NAME);

        String results = "";
        Iterator<AnalysisResponseBase.AnalysisPhase> it = response.getFieldNameAnalysis(ZbZskData.FIELD_KEYWORDS)
                .getQueryPhases().iterator();
        while (it.hasNext()) {
            AnalysisResponseBase.AnalysisPhase pharse = (AnalysisResponseBase.AnalysisPhase) it.next();
            List<AnalysisResponseBase.TokenInfo> list = pharse.getTokens();
            for (AnalysisResponseBase.TokenInfo info : list) {
                results += " " + (info.getText());
            }
        }
        return results;
    }

再用中文分词的时候,要注意使用的字段一定要支持中文分词。

 /**
     * 对应solr conf/managed-schema keywords字段,此处必须为集合形式存在
     */
    @Indexed(name = FIELD_KEYWORDS, type = "text_ik")
    private Set<String> keywords;

在solr中的配置为

	<field name="name" type="string" indexed="true" stored="true"/>
	<field name="type" type="string" indexed="true" stored="true"/>
	<field name="table_name" type="text_ik" indexed="true" stored="true"/>
	<field name="keywords" type="text_ik" indexed="true" stored="true" multiValued="true"/>

	<copyField source="keywords" dest="keywords"/>
	<copyField source="name" dest="keywords"/>
	<copyField source="type" dest="keywords"/>
	<copyField source="table_name" dest="keywords"/>

添加测试代码

@Test
public void analysis() throws IOException, SolrServerException {
    System.out.println(musicRepository.getAnalysis("三千越甲可吞吴"));
}

在这里插入图片描述
接下来封装solr对数据处理的接口:

public interface SolrServiceAPI<T> {

    //新增单条数据
    void addBean(T t);

    //批量添加数据
    void addList(List<T> tList);

    //根据id查找
    void findById(String id);


    //查询并分页
    ScoredPage<T> queryByPage(long pageIndex, int pageSize);

    //根据Id查询
    void deleteById(String id);

    //关键字查询
    ScoredPage<T> searchByKeyword(String searchTerm, long pageIndex, int pageSize);

  //语句搜索

    ScoredPage<T> searchBySentence(String sentence, long pageIndex, int pageSize)
            throws IOException, SolrServerException;

    // 屏蔽无需显示的字段

    ScoredPage<T> searchByNameProjection(String searchName, long pageIndex, int pageSize);

	// 高亮分页查询
 
    Map<String, Object> search(Map searchMap);
}

对应的实现类:

@Service
public class SolrService extends BaseService implements SolrServiceAPI<User> {

    @Autowired
    SolrTemplate solrTemplate;


 
    @Override
    public void addBean(ZbZskData zb_zsk_datacenter) {
        //将数据添加到solr中
        solrTemplate.saveBean(ZbZskData.CORE_NAME, zb_zsk_datacenter);
        //提交
        solrTemplate.commit(ZbZskData.CORE_NAME);
    }


    @Override
    public void addList(List<ZbZskData> zb_zsk_datacenters_list) {
        solrTemplate.saveBeans(ZbZskData.CORE_NAME, zb_zsk_datacenters_list);
        solrTemplate.commit(ZbZskData.CORE_NAME);
    }

   @Override
    public void findById(String id) {
        Optional<ZbZskData> music = solrTemplate.getById(ZbZskData.CORE_NAME, id, ZbZskData.class);
        System.out.println(music);
    }

    //分页查询
    @Override
    public ScoredPage<ZbZskData> queryByPage(long pageIndex, int pageSize) {
        // 创建查询条件,查询所有使用 *:*
        Query query = new SimpleQuery("*:*");
        // 设置分页条件
        query.setOffset(pageIndex);
        query.setRows(pageSize);
        // 执行分页查询
        ScoredPage<ZbZskData> zsk = solrTemplate.queryForPage(ZbZskData.CORE_NAME, query, ZbZskData.class);
        // 解析分页结果
        for (ZbZskData zsk_datacenter : zsk) {
            System.out.println(zsk_datacenter.getZB_ZSK_KEYWORDS());
            System.out.println(zsk_datacenter.getZB_ZSK_DOC_NAME());
        }
        System.out.println("总记录的数 :  " + zsk.getTotalElements());
        System.out.println("总页数 : " + zsk.getTotalPages());
        return zsk;
    }

    //根据Id删除
    @Override
    public void deleteById(String id) {
        solrTemplate.deleteByIds(ZbZskData.CORE_NAME, id);
        // 提交
        solrTemplate.commit(ZbZskData.CORE_NAME);
    }

    //关键字搜索
    @Override
    public ScoredPage<ZbZskData> searchByKeyword(String searchTerm, long pageIndex, int pageSize) {
        String[] words = searchTerm.toUpperCase().split(" ");
        String[] contidionFields = new String[]{ZbZskData.FIELD_KEYWORDS};
        Criteria conditions = createSearchConditions(contidionFields, words);
        SimpleQuery search = new SimpleQuery(conditions);
        search.setOffset(pageIndex);
        search.setRows(pageSize);
        ScoredPage<ZbZskData> page = solrTemplate.queryForPage(ZbZskData.CORE_NAME, search, ZbZskData.class);
        System.out.println("总记录的数 :  " + page.getTotalElements());
        System.out.println("总页数 : " + page.getTotalPages());
        return page;
    }

 
    //构造搜索条件
    private Criteria createSearchConditions(String[] conditionFileds, String[] words) {
        Criteria conditions = null;

        for (String word : words) {
            if (conditions == null) {
                for (int i = 0; i < conditionFileds.length; i++) {
                    if (i == 0) {
                        conditions = new Criteria(conditionFileds[i]).contains(word);
                    } else {
                        conditions = conditions.or(new Criteria(conditionFileds[i]).contains(word));
                    }
                }
            } else {
                for (String condition : conditionFileds) {
                    conditions = conditions.or(new Criteria(condition).contains(word));
                }
            }
        }

        return conditions;
    }

    //语句搜索
    @Override
    public ScoredPage<ZbZskData> searchBySentence(String sentence, long pageIndex, int pageSize) throws IOException, SolrServerException {
        String words = getAnalysis(sentence.toUpperCase());
        String trim = words.trim();
        return searchByKeyword(trim, pageIndex, pageSize);
    }
    @Override
    public ScoredPage<ZbZskData> searchByNameProjection(String searchName, long pageIndex, int pageSize) {
        String[] words = searchName.toUpperCase().split(" ");
        String[] contidionFields = new String[]{ZbZskData.FIELD_KEYWORDS, ZbZskData.FIELD_ZB_ZSK_DOC_NAME};
        Criteria conditions = createSearchConditions(contidionFields, words);
        SimpleQuery search = new SimpleQuery(conditions);

        // 投影
        search.addProjectionOnField(ZbZskData.FIELD_KEYWORDS);
        search.setOffset(pageIndex);
        search.setRows(pageSize);
        ScoredPage<ZbZskData> page = solrTemplate.queryForPage(ZbZskData.CORE_NAME, search, ZbZskData.class);
        return page;
    }

   // 高亮分页查询
    @Override
    public Map<String, Object> search(Map searchMap) {
        //使用高亮查询
        HighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("*:*"));

        highlightConfig(query);

        if (searchMap != null) {
            //如果searchMap不为null;则根据关键词进行搜索;关键词都为字符串
            String keywords = (String) searchMap.get("keywords");
            //关键词搜索从标题、品牌、商家名字、分类名字
            if (StringUtils.isNoneBlank(keywords)) {
                //关键词不为空:创建条件进行搜索--->进行过滤搜索
                //.is表示在索引库里面搜索包含keyword的数据
                Criteria criteria = new Criteria(ZbZskData.FIELD_KEYWORDS).is(keywords);

                //添加查询条件
                query.addCriteria(criteria);
            }
        }
        //设置分页展示:下标从0开始,一页显示30条数据
        query.setOffset(0L);
        query.setRows(10);
        //-----------------------------------高亮域的替换显示
        //获取socredPage对象
        HighlightPage<ZbZskData> scoredPage = solrTemplate.queryForHighlightPage(ZbZskData.CORE_NAME, query, ZbZskData.class);
        highlightReplace(scoredPage);
        //返回1:获取Item所有数据
        List<ZbZskData> itemList = scoredPage.getContent();
        //返回2:显示多少条数据
        long totalElements = scoredPage.getTotalElements();
        //将数据封装成Map集合进行返回
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("rows", itemList);
        dataMap.put("total", totalElements);
        return dataMap;
    }

    //设置高亮域
    public void highlightConfig(HighlightQuery query) {
        HighlightOptions highlightOptions = new HighlightOptions();

        //高亮域的设置:1 高亮域 2 前缀、后缀
        highlightOptions.addField(ZbZskData.FIELD_KEYWORDS).addField(ZbZskData.FIELD_ZB_ZSK_DOC_NAME);
        highlightOptions.setSimplePrefix("<span style='color:red;'>");
        highlightOptions.setSimplePostfix("</span>");

        //将高亮配置设置到高亮选项中
        query.setHighlightOptions(highlightOptions);
    }

	//高亮
    public void highlightReplace(HighlightPage<ZbZskData> scoredPage) {
        //获取所有数据 所有数据,拥有[高亮]也拥有[非高亮]
        List<HighlightEntry<ZbZskData>> highlighted = scoredPage.getHighlighted();

        //循环所有数据
        for (HighlightEntry<ZbZskData> itemHighlightEntry : highlighted) {
            //获取非高亮数据
            ZbZskData music = itemHighlightEntry.getEntity();

            //获取高亮值 [如果只有一个高亮域,则集合中只有一条数据]
            List<HighlightEntry.Highlight> highlights = itemHighlightEntry.getHighlights();

            if (highlights != null && highlights.size() > 0) {
                //普通高亮值
                HighlightEntry.Highlight highlight = highlights.get(0);

                //获取高亮碎片
                List<String> snipplets = highlight.getSnipplets();

                if (snipplets != null && snipplets.size() > 0) {
                    //获取高亮碎片
                    StringBuffer buffer = new StringBuffer();
                    for (String snipplet : snipplets) {
                        buffer.append(snipplet);
                    }
                    //将非高亮替换成高亮
                    music.setZB_ZSK_KEYWORDS(buffer.toString());
                }
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值