SSM(二)Lucene 全文检索(上)

简介: 大家平时肯定都有用过全文检索工具,最常用的百度谷歌就是其中的典型。如果自己能够做一个那是不是想想就逼格满满呢。Apache就为我们提供了这样一个框架,以下就是在实际开发中加入Lucene的一个小Demo。

获取Maven依赖



首先看一下实际运行的效果图:




这个项目是基于之前使用IDEA搭建的SSM的基础上进行增加的,建议小白先看下一我。上一篇博客,以及共享在Github上的源码。 以下是Lucene所需要的依赖:


org.apache.lucene
            lucene-core
            ${lucene.version}
            org.apache.lucene
            lucene-queryparser
            ${lucene.version}
            org.apache.lucene
            lucene-analyzers-common
            ${lucene.version}
            org.apache.lucene
            lucene-analyzers-smartcn
            ${lucene.version}
            org.apache.lucene
            lucene-highlighter
            ${lucene.version}


具体的用途我都写有注释。 在IDEA中修改了Pom.xml文件之后只需要点击如图所示的按钮即可重新获取依赖:



编写Lucene工具类


这个工具类中的具体代码我就不单独提出来说了,每个关键的地方我都写有注释,不清楚的再讨论。


package com.crossoverJie.lucene;
import com.crossoverJie.pojo.User;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import java.io.StringReader;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
import com.crossoverJie.util.*;
/**
 * 博客索引类
 * @author Administrator
 *
 */
public class LuceneIndex {
  private Directory dir=null;
  /**
   * 获取IndexWriter实例
   * @return
   * @throws Exception
   */
  private IndexWriter getWriter()throws Exception{
    /**
     * 生成的索引我放在了C盘,可以根据自己的需要放在具体位置
     */
    dir= FSDirectory.open(Paths.get("C://lucene"));
    SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer();
    IndexWriterConfig iwc=new IndexWriterConfig(analyzer);
    IndexWriter writer=new IndexWriter(dir, iwc);
    return writer;
  }
  /**
   * 添加博客索引
   * @param user
   */
  public void addIndex(User user)throws Exception{
    IndexWriter writer=getWriter();
    Document doc=new Document();
    doc.add(new StringField("id",String.valueOf(user.getUserId()), Field.Store.YES));
    /**
     * yes是会将数据存进索引,如果查询结果中需要将记录显示出来就要存进去,如果查询结果
     * 只是显示标题之类的就可以不用存,而且内容过长不建议存进去
     * 使用TextField类是可以用于查询的。
     */
    doc.add(new TextField("username", user.getUsername(), Field.Store.YES));
    doc.add(new TextField("description",user.getDescription(), Field.Store.YES));
    writer.addDocument(doc);
    writer.close();
  }
  /**
   * 更新博客索引
   * @param user
   * @throws Exception
   */
  public void updateIndex(User user)throws Exception{
    IndexWriter writer=getWriter();
    Document doc=new Document();
    doc.add(new StringField("id",String.valueOf(user.getUserId()), Field.Store.YES));
    doc.add(new TextField("username", user.getUsername(), Field.Store.YES));
    doc.add(new TextField("description",user.getDescription(), Field.Store.YES));
    writer.updateDocument(new Term("id", String.valueOf(user.getUserId())), doc);
    writer.close();
  }
  /**
   * 删除指定博客的索引
   * @param userId
   * @throws Exception
   */
  public void deleteIndex(String userId)throws Exception{
    IndexWriter writer=getWriter();
    writer.deleteDocuments(new Term("id", userId));
    writer.forceMergeDeletes(); // 强制删除
    writer.commit();
    writer.close();
  }
  /**
   * 查询用户
   * @param q 查询关键字
   * @return
   * @throws Exception
   */
  public List searchBlog(String q)throws Exception{
    /**
     * 注意的是查询索引的位置得是存放索引的位置,不然会找不到。
     */
    dir= FSDirectory.open(Paths.get("C://lucene"));
    IndexReader reader = DirectoryReader.open(dir);
    IndexSearcher is=new IndexSearcher(reader);
    BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
    SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer();
    /**
     * username和description就是我们需要进行查找的两个字段
     * 同时在存放索引的时候要使用TextField类进行存放。
     */
    QueryParser parser=new QueryParser("username",analyzer);
    Query query=parser.parse(q);
    QueryParser parser2=new QueryParser("description",analyzer);
    Query query2=parser2.parse(q);
    booleanQuery.add(query, BooleanClause.Occur.SHOULD);
    booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
    TopDocs hits=is.search(booleanQuery.build(), 100);
    QueryScorer scorer=new QueryScorer(query);
    Fragmenter fragmenter = new SimpleSpanFragmenter(scorer);
    /**
     * 这里可以根据自己的需要来自定义查找关键字高亮时的样式。
     */
    SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("","");
    Highlighter highlighter=new Highlighter(simpleHTMLFormatter, scorer);
    highlighter.setTextFragmenter(fragmenter);
    List userList=new LinkedList();
    for(ScoreDoc scoreDoc:hits.scoreDocs){
      Document doc=is.doc(scoreDoc.doc);
      User user=new User();
      user.setUserId(Integer.parseInt(doc.get(("id"))));
      user.setDescription(doc.get(("description")));
      String username=doc.get("username");
      String description=doc.get("description");
      if(username!=null){
        TokenStream tokenStream = analyzer.tokenStream("username", new StringReader(username));
        String husername=highlighter.getBestFragment(tokenStream, username);
        if(StringUtil.isEmpty(husername)){
          user.setUsername(username);
        }else{
          user.setUsername(husername);
        }
      }
      if(description!=null){
        TokenStream tokenStream = analyzer.tokenStream("description", new StringReader(description));
        String hContent=highlighter.getBestFragment(tokenStream, description);
        if(StringUtil.isEmpty(hContent)){
          if(description.length()<=200){
            user.setDescription(description);
          }else{
            user.setDescription(description.substring(0, 200));
          }
        }else{
          user.setDescription(hContent);
        }
      }
      userList.add(user);
    }
    return userList;
  }
}


相关文章
|
前端开发 关系型数据库 MySQL
SSM(二)Lucene 全文检索(下)
大家平时肯定都有用过全文检索工具,最常用的百度谷歌就是其中的典型。如果自己能够做一个那是不是想想就逼格满满呢。Apache就为我们提供了这样一个框架,以下就是在实际开发中加入Lucene的一个小Demo。
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的大学生校园兼职附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的大学生校园兼职附带文章和源代码部署视频讲解等
44 8
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的电影评价系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的电影评价系统附带文章和源代码部署视频讲解等
35 8
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的停车场微信小程序附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的停车场微信小程序附带文章和源代码部署视频讲解等
29 6
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
27 5
基于ssm+vue.js+uniapp小程序的使命召唤游戏助手附带文章和源代码部署视频讲解等
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的移动端购物系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的移动端购物系统附带文章和源代码部署视频讲解等
28 4
基于ssm+vue.js+uniapp小程序的移动端购物系统附带文章和源代码部署视频讲解等
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的跑腿平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的跑腿平台附带文章和源代码部署视频讲解等
33 10
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的疫情期间学生请假与销假系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的疫情期间学生请假与销假系统附带文章和源代码部署视频讲解等
57 7
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的英语学习交流平台附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的英语学习交流平台附带文章和源代码部署视频讲解等
27 7
|
27天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的马拉松报名系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的马拉松报名系统附带文章和源代码部署视频讲解等
30 6