Lucene全文搜索学习笔记(三)

个人笔记之用,如有错误,恳请批评指正。


高亮,多字段查询,分页查询。

分页查询,接上

若查询第二页,每页5条。查询10条。遍历取回6-10条。需判断总条数与需要条数的关系

//总记录数小于end,说明scoreDocs不满end条。即返回的是start--totalHits条。否则返回的是start--end条
           ScoreDoc[] scoreDocs = topDocs.scoreDocs;
           int size = end;
           if(topDocs.totalHits<end) {
              size = topDocs.totalHits;
           }


IndexWriterUtil的编写:整个项目唯一一个IndexWriter,并且在虚拟机关闭时自动close();

//注册虚拟机关闭线程
       Runtime.getRuntime().addShutdownHook(new Thread(){
 
           @Override
           public void run() {
              try {
                  indexWriter.close();
                  System.out.println("indexWriter已经关闭了!");
              } catch (CorruptIndexException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }
           }
       });


做系统不仅要考虑功能,还要考虑非功能的东西,比如说性能,可维护性,交互性等。

IKAnalyzer中文分词器:开源的,轻量级的分词器。

使用IKAnalyzer,当参数为true时,表示使用最大词长分词,false表示使用细粒度分词

步骤:

1、  导包

2、  配置文件IKAnalyzer.cfg.xml到src目录下

3、  禁用词汇ext_stopword.dic和自定义词汇mydict.dic放到src目录下(/)(格式:第一行空格换行,并注意保存的编码要一致

禁用词汇不建立索引库,所以搜索不到。但是会存储进索引库。

4、   //使用IKAnalyzer,当参数为true时,表示使用最大词长分词,false表示使用细粒度分词

IKAnalyzer = new IKAnalyzer(true);

IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(), LuceneUtil.getAnalyzer(), LuceneUtil.getMaxFieldLength());

注意:当indexWriter用了IKAnalyzer以后,indexSearcher也要用IKAnalyzer


排序和多字段查询

//创建排序字段,参数一:指定排序字段;参数二:字段类型;参数三:设置升序或子降序,true为降序

         SortField goodsId = new SortField("goodsId",SortField.INT,true);

         Sort sort=new Sort();

         //设置排序字段(可以多个字段)到sort对象中,排序的优先级,前者优先于后者

         sort.setSort(goodsId,其它SortField对象);          

         //使用IKQueryParser进行多字段数据查询

         Query query=IKQueryParser.parseMultiField(new String[]{"goodsName","goodsRemark"},keyword);       

         //执行查询,使用search(Query query , Filter filter , int n , Sort sort)方法,返回20条记录,加入排序设置信息

         TopDocs topDocs = indexSearcher.search(query, null,20,sort);//null过滤器

 

排序:

new SortField(“指定排序字段”,“字段类型”,“true:升序 false:降序”);

sort = new sort();

sort.setSort(多个sortField);

多字段:

query = IKQueryParser.parseMultiField(new String[]{“字段名”},“keyword”);

查询:

indexSearcher.search(query,null,20,sort);

 

//排序+多字段查询
    public void searchBySortAndMultiField(String keyword){
        try {
            IndexSearcher indexSearcher = IndexSearcherUtil.getIndexSearcher();
            //设置排序
            SortField idField = new SortField("id", SortField.INT, false);
            //SortField contentField = new SortField("content",SortField.STRING,false);
            Sort sort = new Sort();
            sort.setSort(idField);
            //设置多字段查询
            Query query = IKQueryParser.parseMultiField(new String[]{"title","content"}, keyword);
            TopFieldDocs topFieldDocs = indexSearcher.search(query, null, 20, sort);
            System.out.println("总匹配数:"+topFieldDocs.totalHits);
            ScoreDoc[] scoreDocs = topFieldDocs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                Document doc = indexSearcher.doc(scoreDoc.doc);
                System.out.println("title:"+doc.get("title")+"content:"+doc.get("content"));
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


高亮:

获取到Document对象后,对doc中指定字段的指定内容利用HighLighter对象进行高亮返回带有高亮格式的指定字段值,重新setValuedocument中的对应field中,封装到对象输出。

具体步骤:

Document doc = indexSearcher.doc(scoreDocs[i].doc);
//设置高亮格式
Formatter fomatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
//设置需要高亮的关键字,指定查询信息
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(fomatter,scorer);
//制定高亮后的长度,需要SimpleFragmenter类型参数,指定20
int length = 20;
highlighter.setTextFragmenter(new SimpleFragmenter(length));
//设置对哪些字段进行高亮,返回高亮后的结果
String titleResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "title", doc.get("title"));
String contentResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "content", doc.get("content"));


对返回的String判空:

Document doc = indexSearcher.doc(scoreDocs[i].doc);
//设置高亮格式
Formatter fomatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
//设置需要高亮的关键字,指定查询信息
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(fomatter,scorer);
//制定高亮后的长度,需要SimpleFragmenter类型参数,指定20
int length = 20;
highlighter.setTextFragmenter(new SimpleFragmenter(length));
//设置对哪些字段进行高亮,返回高亮后的结果
String titleResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "title", doc.get("title"));
String contentResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "content", doc.get("content"));

 

对HighLighterUtils的抽取

Document doc = indexSearcher.doc(scoreDocs[i].doc);
//设置高亮格式
Formatter fomatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
//设置需要高亮的关键字,指定查询信息
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(fomatter,scorer);
//制定高亮后的长度,需要SimpleFragmenter类型参数,指定20
int length = 20;
highlighter.setTextFragmenter(new SimpleFragmenter(length));
//设置对哪些字段进行高亮,返回高亮后的结果
String titleResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "title", doc.get("title"));
String contentResult = highlighter.getBestFragment(LuceneUtil.getIKAnalyzer(), "content", doc.get("content"));

索引库优化

indexWriter.optimize()方法使用

新增数据时在提交前使用optimize()方法: 将把产生.cfs的文档和原来的文档压缩并合并为一个

修改操作类的保存数据方法

indexWriter.optimize();

indexWriter.setMergeFactor()方法使用

关键代码:

//通过设置合并因子合并文件,如下:产生三个cfs文档(包括合并的)将压缩合并成一个

indexWriter.setMergeFactor(3);


写在最后,lucene初步入门,能实现初步的增删改查,分段、排序、高亮以及索引优化。

增删改查

Term 对应索引表里的关键词及字段 newTerm(“字段名”,”字段值”)

TopDocs只包括总记录数和文档编号(scoreDoc.doc)

           ScoreDoc[] scoreDocs = topDocs.scoreDocs;
           Document document = indexSearcher.doc(scoreDoc.doc);

通过文档编号再次查询searcher.doc(scoreDoc.doc)返回document

update原则:根据字段的值进行修改数据内容,先删除再添加。如果字段值不存在,则新增一条记录(文档),如果字段值唯一,那就相当于根据主键修改数据;如果字段值对应多条记录(文档),则其他记录(文档)将被逻辑删除后,再添加一条记录(文档)。

Delete原则:根据传入的字段值搜索对应的记录(文档),进行删除。


使用细节:

尽量减少不必要的字段的存储。Store.YES/Store.NO

不需要检索的内容尽量不要建立索引。Index.ANALYZED/Index.NOT_ANALYZED/Index.NO

非文本格式需要提前转化为字符串。

需要整体存放的内容不要分词,例如:ID、价格、专业词。Index.NOT_ANALYZED
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值