ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【lucene-plus】初始化索引

2021-10-09 23:30:14  阅读:155  来源: 互联网

标签:初始化 IndexFileEnum getName lucene 索引 plus params


       lucene-plus依赖spring-boot 2.xx实现,使用spring或其他spring-boot工程的同学可根据自己的需求调整源码,源码坐标:lucene-plus: 基于lucene进行通用CRUD的封装,享受lucene丝滑般的操作。

        有需求的同学可以fork工程的master分支进行调整开发,原则上不建议直接下载源码。lucene本身没有“初始化索引”的概念,所到之处皆是new,这给我一种很不爽的体验,所以创建lucene-plus的时候第一个实现的功能便是“初始化索引”,为什么是“lucene-plus”?因为我只是基于lucene进行了顶层的封装,而没有调整lucene任何源码。下面开始介绍lucene-plus如何进行索引的初始化。

1、引入maven坐标:

   <dependency>
      <groupId>cn.juque</groupId>
      <artifactId>lucene-plus</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

2、application-${profile}.yml文件添加配置:

# 指定索引所在目录
lucene:
  index:
    directory: D:\DOC\multiFile\index\

3、添加lucene-plus的扫描目录(lucene-plus依赖hutool工具的bean操作,所以"cn.hutool.extra.spring"必须能被工程扫描到):

@ComponentScans(value = {@ComponentScan("cn.juque.luceneplus"), @ComponentScan("cn.hutool.extra.spring")})

4、至此,便已完成lucene-plus的依赖引入。比如我们需要初始化一个关于文件信息的索引,我们首先需要实现接口:IndexTemplate,定义整个索引的json形式:

@Component("indexFileHandler")
public class IndexFileHandler implements IndexTemplate {

    @Override
    public String getTemplate() {
        return "{\n"
            + "    \"indexName\":\"file_info\",\n"
            + "    \"fieldDTOList\":[\n"
            + "        {\n"
            + "            \"fieldName\":\"module_id\",\n"
            + "            \"fieldType\":\"STRING\",\n"
            + "            \"value\":\"${module_id}\",\n"
            + "            \"store\":\"YES\"\n"
            + "        },\n"
            + "        {\n"
            + "            \"fieldName\":\"server_path\",\n"
            + "            \"fieldType\":\"STRING\",\n"
            + "            \"value\":\"${server_path}\",\n"
            + "            \"store\":\"YES\"\n"
            + "        },\n"
            + "        {\n"
            + "            \"fieldName\":\"server_file_name\",\n"
            + "            \"fieldType\":\"STRING\",\n"
            + "            \"value\":\"${server_file_name}\",\n"
            + "            \"store\":\"YES\"\n"
            + "        },\n"
            + "        {\n"
            + "            \"fieldName\":\"client_file_name\",\n"
            + "            \"fieldType\":\"STRING\",\n"
            + "            \"value\":\"${client_file_name}\",\n"
            + "            \"store\":\"YES\"\n"
            + "        },\n"
            + "        {\n"
            + "            \"fieldName\":\"file_size\",\n"
            + "            \"fieldType\":\"DOUBLE\",\n"
            + "            \"value\":\"${file_size}\"\n"
            + "        }\n"
            + "    ]\n"
            + "}";
    }
}

索引参数:

参数:描述
indexName索引名称
fieldDTOList字段信息的列表
fieldDTOList.fieldName字段名称
fieldDTOList.fieldType字段类型
fieldDTOList.value当前保留参数,没有实际意义
fieldDTOList.store是否存储。YES:存储;NO:不存储
fieldDTOList.point是否支持范围查询,只对fieldType:{INTEGER、LONG、DOUBLE}有效
fieldDTOList.analyzer分词器,支持的分词器参考:AnalyzerEnum

完成索引的json定义,启动服务后索引信息会自动完成初始化,后续新增、编辑都会基于初始化的索引信息进行Document实例化。(注:索引字段只允许增量操作,变更、删除操作均无效,索引名称变更无效)

5、查询操作(支持查询单个Document,普通分页、滚动式分页):

BooleanQuery.Builder builder = new BooleanQuery.Builder();
        Term term = new Term(IndexFileEnum.SERVER_FILE_NAME.getName(), serverName);
        TermQuery termQuery = new TermQuery(term);
        builder.add(termQuery, Occur.MUST);
        Document document = this.documentPlusService.searchDocument(IndexFileEnum.FILE_INFO.getName(), builder);

普通分页查询实现的是逻辑分页,目前支持最大20万数据量的分页。如果有同学能实现物理分页,可以分享下。

6、新增文档操作:

// 保存
        Map<String, Object> params = CollUtil.newHashMap(10);
        params.put(IndexFileEnum.MODULE_ID.getName(), multiFileBo.getModuleId());
        params.put(IndexFileEnum.CLIENT_FILE_NAME.getName(), multiFileBo.getFileName());
        params.put(IndexFileEnum.SERVER_FILE_NAME.getName(), serverName);
        params.put(IndexFileEnum.SERVER_PATH.getName(), serverPath);
        params.put(IndexFileEnum.DOWNLOAD_TIMES.getName(), 0);
        params.put(IndexFileEnum.UPLOAD_USER_ID.getName(), multiFileBo.getUserId());
        try {
            this.documentPlusService.addDocument(IndexFileEnum.FILE_INFO.getName(), params);
        } catch (IOException e) {
            log.error("save file error", e);
            throw new AppException(InternetStorageMsgEnum.SYSTEM_ERROR);
        }

lucene-plus会根据fieldName映射实例化Field,所以大家如果新增了字段,要先调整索引模板,否则单独添加到Map里面将无法生效。

7、更新操作:

BooleanQuery.Builder builder = new BooleanQuery.Builder();
        serverNames.forEach(t->{
            Term term = new Term(IndexFileEnum.SERVER_FILE_NAME.getName(), t);
            builder.add(new TermQuery(term), Occur.SHOULD);
        });
        Map<String, Object> params = CollUtil.newHashMap(1);
        params.put(IndexFileEnum.IS_VALID.getName(), Boolean.TRUE.toString());
        this.documentPlusService.updateDocument(IndexFileEnum.FILE_INFO.getName(), builder, params);

api会根据传递过来的条件查出相关Document,然后执行delete-insert。lucene的updateDocument的实现逻辑实际也是delete-insert,区别在于:lucene-plus实现了Document的局部更新,而原生update方法是全量字段更新;

8、删除操作,与原生的删除操作并没有多大区别。至此,基于lucene-plus的增删改查的介绍也告一段落了。

        文章结尾记录下开发过程遇到的问题,如有答案的同学,烦请告知一下

1、lucene-plus的更新操作是先查出来,然后把Document和Maps进行合并,最后根据条件执行delete操作,把合并后的Document重新保存。在实际操作中,最后一步调用原生的addDocument保存一直没成功,或是用原生的updateDocument也只是删除成功,而没有保存新的Document。无奈下,我改成调用lucene-plus的addDocument居然保存成功了,这个骚操作一直没整明白。。。

标签:初始化,IndexFileEnum,getName,lucene,索引,plus,params
来源: https://blog.csdn.net/shenya2/article/details/120680142

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有