luncene全文搜索引擎(中文分词)

xiaoxiao2021-02-28  64

最近在学luncene全文检索。跟着学习视频学的,推荐www.java1234.com上去学下。

关于全文检索:推荐看下全文检索的原理。这里我就不再写了,下面把利用中文分词检索查询的demo给贴出来,以供以后使用。

首先是pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.luncene.demo</groupId> <artifactId>LunceneDemo</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>LunceneDemo Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- lucnene核心包 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>5.5.0</version> </dependency> <!-- lucnene解析包 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-queryparser</artifactId> <version>5.5.0</version> </dependency> <!-- lucene 公共包分析器 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-common</artifactId> <version>5.5.0</version> </dependency> <!-- 中文分词 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-analyzers-smartcn</artifactId> <version>5.5.0</version> </dependency> <!-- 关键词高亮显示 --> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-highlighter</artifactId> <version>5.5.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>LunceneDemo</finalName> </build> </project>

然后是创建索引的类,这里只是根据java1234课程进行了简单的练习,大家如果需要做检索的话, 就会把数据库查询出来的结果信息可以换了。

Indexer.java

package com.java1234.luncene06; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.*; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import java.nio.file.Paths; /**创建中文索引 * Created by T430 on 2017/8/2. */ public class Indexer { private Integer ids[]={1,2,3}; private String citys[]={"青岛","南京","上海"}; private String descs[]={ "青岛是一个美丽的城市", "南京是一个文化的城市南京,简称宁,是江苏省会,地处中国东部地区,长江下游,濒江近海。全市下辖11个区,总面积6597平方公里,2013年建成区面积752.83平方公里,常住人口818.78万,其中城镇人口659.1万人。[1-4] “江南佳丽地,金陵帝王州”,南京拥有着6000多年文明史、近2600年建城史和近500年的建都史,是中国四大古都之一,有“六朝古都”、“十朝都会”之称,是中华文明的重要发祥地,历史上曾数次庇佑华夏之正朔,长期是中国南方的政治、经济、文化中心,拥有厚重的文化底蕴和丰富的历史遗存。[5-7] 南京是国家重要的科教中心,自古以来就是一座崇文重教的城市,有“天下文枢”、“东南第一学”的美誉。截至2013年,南京有高等院校75所,其中211高校8所,仅次于北京上海;国家重点实验室25所、国家重点学科169个、两院院士83人,均居中国第三。[8-10] 。\",\n", "上海是一个金融城市" }; private Directory dir;//字典 /** * 获取inderWriter示例 * @return * @throws Exception */ private IndexWriter getWriter() throws Exception{ // Analyzer analyzer =new StandardAnalyzer();//标准分词器 //中文分词器 SmartChineseAnalyzer analyzer= new SmartChineseAnalyzer(); IndexWriterConfig iwc = new IndexWriterConfig(analyzer); IndexWriter writer=new IndexWriter(dir,iwc);//把分的词和字典都写入进去 return writer; } /** * 构造器 * @param indexDir 保存的地址 * @throws Exception */ private void index(String indexDir) throws Exception{ dir = FSDirectory.open(Paths.get(indexDir)); IndexWriter writer = getWriter(); for (int i = 0; i <ids.length ; i++) { Document doc=new Document();//这里选用的是luncene的document,别选错了哦 /** * 这个是把ID加进去,因为ID是int类型的,所以需要用到的是IntField,由于占的空间不大,所以选择YES保存进去 */ doc.add(new IntField("id",ids[i], Field.Store.YES)); /** * 这个是把String类型的保存进去,算是标签吧(个人理解),所占空间不大,所以也选择YES保存进去 */ doc.add(new StringField("city",citys[i],Field.Store.YES)); /** * 这个是把内容保存进去,大字段的所以选择的是TextField */ doc.add(new TextField("desc",descs[i],Field.Store.YES)); //添加文档 writer.addDocument(doc); } writer.close();//写完以后就要关闭流,保证性能 } public static void main(String[] args) { try { new Indexer().index("E:\\lucene6"); } catch (Exception e) { e.printStackTrace(); } } } 下面就开始创建检索的类

package com.java1234.luncene06; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; 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; /**中文分词查询及高亮显示 * Created by T430 on 2017/8/2. */ public class Seracher { /** * 查询 * @param indexDir 索引路径 * @param q 查询用的关键词 * @throws Exception */ public static void search(String indexDir, String q) throws Exception{ Directory dir= FSDirectory.open(Paths.get(indexDir));//获取字典内容 IndexReader reader = DirectoryReader.open(dir);//读出字典 //索引查询器 IndexSearcher is= new IndexSearcher(reader); // Analyzer analyzer =new StandardAnalyzer();//标准分词器 SmartChineseAnalyzer analyzer=new SmartChineseAnalyzer();//中文分词器 //查询解析 QueryParser parser= new QueryParser("desc",analyzer); //格式化查询 Query query=parser.parse(q); //查询前的时间 long start= System.currentTimeMillis(); //查询,返回前十的文档 TopDocs hits=is.search(query,10); //查询后的时间 long end=System.currentTimeMillis(); System.out.println("匹配:"+q+",中共花费了:"+(end-start )+"毫秒"); QueryScorer scorer= new QueryScorer(query);//片段得分,计算得分,把得分高的片段计算出来 Fragmenter fragmenter= new SimpleSpanFragmenter(scorer);//把得分放进去,进行格式化 //设置成html的格式,默认的是粗体, 咱们可以给他改成粗体,红色 SimpleHTMLFormatter simpleHTMLFormatter= new SimpleHTMLFormatter("<b><font color='red'>","</font></b>"); Highlighter highlighter=new Highlighter(simpleHTMLFormatter,scorer);//高亮显示片段得分高的部分 highlighter.setTextFragmenter(fragmenter);//把得分的摘要设置成text显示出来 //查询到的文档 for (ScoreDoc scoreDoc: hits.scoreDocs){ //根据主键ID获取文档 Document doc= is.doc(scoreDoc.doc); System.out.println(doc.get("city"));//输出城市 String desc=doc.get("desc");//完整的desc数据 System.out.println(desc);//输出完整的desc /** * 如果查询得到的desc不为空,则进行高亮,片段显示 */ if (desc!=null){ //获取很多的片段 TokenStream tokenStream= analyzer.tokenStream("desc",new StringReader(desc)); String ZhaiYao= highlighter.getBestFragment(tokenStream,desc);//把权重高的片段摘要显示出来 System.out.println("显示高亮的关键词片段:===》"+ZhaiYao); } } reader.close();//关闭 } public static void main(String[] args) { String indexDir = "E:\\lucene6";//索引目录 String q="南京 厚重";//关键词 try { search(indexDir,q); } catch (Exception e) { e.printStackTrace(); } } }

到此为止。 一个简单的中文全文检索就做好了。 对于一般的搜索来说, 完全够用了。 大家可以对这个再进行封装。  就到这了。  

转载请注明原文地址: https://www.6miu.com/read-1167871.html

最新回复(0)