创新实训 5

2021SC@SDUSC

SolrController

什么是Solr

Solr(读作“solar”)是Apache Lucene项目的开源企业搜索平台。其主要功能包括全文检索、命中标示[1]分面搜索、动态聚类、数据库集成,以及富文本(如WordPDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制。Solr是最流行的企业级搜索引擎,[2]Solr 4还增加了NoSQL支持。[3]

Solr是用Java编写、运行在Servlet容器(如Apache TomcatJetty)的一个独立的全文搜索服务器。 Solr采用了Lucene Java搜索库为核心的全文索引和搜索,并具有类似RESTHTTP/XMLJSONAPI。 Solr强大的外部配置功能使得无需进行Java编码,便可对其进行调整以适应多种类型的应用程序。Solr有一个插件架构,以支持更多的高级定制。

可以认为Solr是一个NoSQL,类似于MongoDB那样的文档型数据库,它拥有很多个core,每个core中有不同的数据集,它支持很多操作,比如分词搜索,模糊搜索效率高,分摊关系型数据库压力。

服务接口

@RestController
@RequestMapping("/solr")
public class SolrController {

    @Autowired
    private SolrService solrService;

    /**
     * 查询方法
     * @param coreName 查询的solr的core名称
     * @param defaultField 默认查询字段
     * @param query 查询关键词
     * @param sortField 排序字段 格式:字段 asc\desc 字段与排序规则用空格分割
     * @param order 排序规则
     * @param start 起始位置
     * @param rows 返回条数
     * @param mode 搜索模式
     * @param filterQueries 补充查询条件 格式:字段:keyword
    */
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    @ResponseBody
    public QueryResults query(String coreName,
                              String defaultField,
                              String query,
                              String sortField,
                              String order,
                              Integer start,
                              Integer rows,
                              String mode,
                              String... filterQueries) throws SolrServerException, IOException {
        return solrService.query(coreName, defaultField, query, sortField, order, start, rows, mode, filterQueries);
    }

    @RequestMapping(value = "/getSVG", method = RequestMethod.POST)
    public String getSVG(String aid, String keyword, String width, String height, String mode) throws SolrServerException, IOException {
        return solrService.getSVG(aid, keyword, width, height, mode);
    }

    @RequestMapping(value = "/getPNG", method = RequestMethod.POST)
    public String getPNG(String pid) throws SolrServerException, IOException, HttpStatusException {
        return solrService.getPNG(pid);
    }

    @RequestMapping(value = "/getPNGs", method = RequestMethod.POST)
    public List<String> getPNGs(String pids) throws SolrServerException, IOException, HttpStatusException {
        return solrService.getPNGs(pids);
    }
}

观察SolrService实现类:

@Component
public class SolrServiceImpl implements SolrService {

    @Autowired
    private SolrClient solrClient;

    @Autowired
    ParserObject m;

    @Autowired
    SolrInput solrInput;

    @Override
    public QueryResults query(String coreName,
                              String defaultField,
                              String query,
                              String sortField,
                              String order,
                              Integer start,
                              Integer rows,
                              String mode,
                              String... filterQueries) throws SolrServerException, IOException {
		...
    }

    ...

    @Override
    public String getSVG(String aid, String keyword, String width, String height, String mode) throws SolrServerException, IOException {
        ...
    }

    @Override
    public String getPNG(String pid) throws HttpStatusException {
        ...
    }

    @Override
    public List<String> getPNGs(String pids) throws HttpStatusException {
        ...
    }
	
    ...
}

我们可以看到他有三个成员,分别是

  • SolrClient
  • ParserObject (没有用)
  • SolrInput (没有用)

我们一个一个看:

SolrClient

SolrClient就是一个Apache帮我们封装好的Solr服务访问器,我们可以通过它来查询数据,它会给我们返回结果

还可以通过它来增删改数据。

ParserObject

用于处理mongoDB返回过来的数据(不过源码中并没有使用这一个成员的地方)

SolrInput

封装了SolrClient,不过也是并没有在源码中用到

首先是query接口:

@Override
public QueryResults query(String coreName,
                          String defaultField,
                          String query,
                          String sortField,
                          String order,
                          Integer start,
                          Integer rows,
                          String mode,
                          String... filterQueries) throws SolrServerException, IOException {

    SolrQueryBuilder solrQueryBuilder = new SolrQueryBuilder();
    SolrQuery solrQuery = solrQueryBuilder.setDefaultField(defaultField)
        .setQuery(query)
        .setSortField(sortField)
        .setOrder(order)
        .setStart(start)
        .setRows(rows)
        .setMode(mode)
        .setFilterQueries(filterQueries)
        .build();

    System.out.println(solrQuery);
    QueryResponse queryResponse = solrClient.query(coreName,solrQuery);
    SolrDocumentList results = queryResponse.getResults();
    System.out.println(results.getNumFound());

    QueryResults queryResults = new QueryResults(results.getNumFound(), results);
    System.out.println(queryResults);

    return queryResults;
}

SolrQueryBuilder 是封装好了的SolrQuery生成器,对于SolrQuery中每一个需要设置的属性都有默认值,并且提供方便的设定查询值得方法,并有规范性检测。

QueryResults 也是封装好的实体,其中只有两个成员,一个是返回的结果SolrDocumentList, 另一个是结果个数

但是实际上SolrDocumentList中已经有获取结果个数得方法了,这个封装完全是多余的。

其次是核心接口getSVG:

@Override
public String getSVG(String aid, String keyword, String width, String height, String mode) throws SolrServerException, IOException {

    //获取aid对应的文章
    JSONArray article_array = this.queryArticle("dms_article","_id", aid);
    SolrDocument article = (SolrDocument) article_array.get(0);

    //得到文章对应的page列表
    List<HashMap<String, String>> list = this.getPageInfo(o2s(JSONObject.parseArray(JSON.toJSONString(article.get("page")))));
    list.remove(list.size()-1);
    ArrayList<PageInfo> page_list = new ArrayList<>();
    for (HashMap<String, String> stringStringHashMap : list) {
        PageInfo info = new PageInfo(stringStringHashMap);
        //进行缩放的操作
        info.setScale(width, height);
        page_list.add(info);
    }

    //获取词的信息
    JSONArray word_array = this.queryWord("dms_word","word", keyword, aid);
    if(!word_array.isEmpty()){
        List<SolrDocument> word_list = new ArrayList<>();
        for(Object o : word_array){
            word_list.add((SolrDocument) o);
        }
        for(SolrDocument s : word_list){
            List<String> point_list = o2s(JSONObject.parseArray(JSON.toJSONString(s.get("position"))));
            for(String p : point_list){
                String[] point_array = p.split("\\|");
                String page = point_array[0];
                for(int i = 1; i < point_array.length; i++){
                    ArrayList<String> position = new ArrayList<>();
                    String[] points = point_array[i].split(";");
                    for(String point : points){
                        String[] point_i = point.split(":");
                        position.add(point_i[0]);
                        position.add(point_i[1]);
                    }
                    for(PageInfo page_info : page_list){
                        if(page_info.getId().equals(page)){
                            page_info.addWordPolygon(position);
                        }
                    }
                }
            }
        }
    }else if (!mode.equals("precise")){
        //每一个字的信息
        solrQueryCharacter(aid, keyword, article, page_list);
    }

    System.out.println(page_list);

    return page_list.toString();
}

先通过aid来查找出文章,然后解析出文章得每一个page,并将其整合成PageInfo对象列表

由于数据库中存储的内容是json风格,需要将其转换成SVG格式,所以封装了很多得操作,比如说如何将json中离散的字符通过word提供的字符序号列表来还原成文字等等。

下面两个getPNG和getPNGs都是通过调用其他微服务(这里是另一个服务器得mysql数据库中的数据)并返回。

总的来说SolrController就是通过solr存储文章数据,并且将json格式得数据转换成SVG格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值