1.导包

2.索引的创建

2.1首先,我们需要定义一个词法分析器。

Analyzer analyzer = new IKAnalyzer();//官方推荐 Analyzer analyzer = new StandardAnalyzer();

2.2第二步,确定索引文件存储的位置,Lucene提供给我们两种方式:

2.2.1本地文件存储

 Directory directory = FSDirectory.open(new File("D:\\JavaWeb\\Lucene"));

2.2.2 内存存储

Directory directory = new RAMDirectory();

2.3第三步,创建IndexWriter,进行索引文件的写入。

IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);

2.4第四步,内容提取,进行索引的存储。

Document doc = new Document();//申请了一个document对象,这个类似于数据库中的表中的一行。
String text = "This is the text to be indexed.";//即将索引的字符串
Field fileNameField = new TextField("fileName", text, Store.YES);
doc.add(fileNameField);//把字符串存储起来
indexWriter.addDocument(doc);//把doc对象加入到索引创建中
indexWriter.close();//关闭IndexWriter,提交创建内容

lucene常见Field

IntField 主要对int类型的字段进行存储,需要注意的是如果需要对InfField进行排序使用SortField.Type.INT来比较,如果进范围查询或过滤,需要采用NumericRangeQuery.newIntRange()
LongField 主要处理Long类型的字段的存储,排序使用SortField.Type.Long,如果进行范围查询或过滤利用NumericRangeQuery.newLongRange(),LongField常用来进行时间戳的排序,保存System.currentTimeMillions()
FloatField 对Float类型的字段进行存储,排序采用SortField.Type.Float,范围查询采用NumericRangeQuery.newFloatRange()
BinaryDocVluesField 只存储不共享值,如果需要共享值可以用SortedDocValuesField
NumericDocValuesField  用于数值类型的Field的排序(预排序),需要在要排序的field后添加一个同名的NumericDocValuesField
SortedDocValuesField 用于String类型的Field的排序,需要在StringField后添加同名的SortedDocValuesField
StringField 用户String类型的字段的存储,StringField是只索引不分词
TextField 对String类型的字段进行存储,TextField和StringField的不同是TextField既索引又分词
StoredField 存储Field的值,可以用IndexSearcher.doc和IndexReader.document来获取此Field和存储的值

实战代码

@Test
public void testIndex() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
BooksMapper booksMapper = ac.getBean(BooksMapper.class); /*Books book= booksMapper.selectByPrimaryKey(4939);
System.out.println(book.getTitle());*/ List<Books> listBooks=booksMapper.selectBookList();
System.out.println(listBooks.size()); Analyzer analyzer = new IKAnalyzer();
Directory directory = FSDirectory.open(new File("D:\\JavaWeb\\Lucene"));
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config); for (int i = 0; i < listBooks.size(); i++) {
Document doc = new Document();//申请了一个document对象,这个类似于数据库中的表中的一行。 String title = listBooks.get(i).getTitle();
Field filedTitle = new TextField("title", title, Store.YES);
doc.add(filedTitle); String isbn = listBooks.get(i).getIsbn();
Field filedISBN = new TextField("isbn", isbn, Store.YES);
doc.add(filedISBN); int wordsCount = listBooks.get(i).getWordscount();
Field filedWordsCount = new LongField("WordsCount", wordsCount, Store.YES);
doc.add(filedWordsCount); indexWriter.addDocument(doc);//把doc对象加入到索引创建中 }
indexWriter.close();//关闭IndexWriter,提交创建内容
}

luke-5.0查看索引结果 (定位到luke-5.0所在的目录,然后输入码命令java -jar luke-5.0.jar

3.索引的查询

@Test
public void testSearch() throws Exception {
// 第一步:创建一个Directory对象,也就是索引库存放的位置。
Directory directory = FSDirectory.open(new File("D:\\temp\\index"));// 磁盘
// 第二步:创建一个indexReader对象,需要指定Directory对象。
IndexReader indexReader = DirectoryReader.open(directory);
// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
Query query = new TermQuery(new Term("fileName", "lucene"));
// 第五步:执行查询。
TopDocs topDocs = indexSearcher.search(query, 10);
// 第六步:返回查询结果。遍历查询结果并输出。
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
int doc = scoreDoc.doc;
Document document = indexSearcher.doc(doc);
// 文件名称
String fileName = document.get("fileName");
System.out.println(fileName);
// 文件内容
String fileContent = document.get("fileContent");
System.out.println(fileContent);
// 文件大小
String fileSize = document.get("fileSize");
System.out.println(fileSize);
// 文件路径
String filePath = document.get("filePath");
System.out.println(filePath);
System.out.println("------------");
}
// 第七步:关闭IndexReader对象
indexReader.close();
}

4.查看标准分析器的分词效果

        @Test
public void testTokenStream() throws Exception {
// 创建一个标准分析器对象
//Analyzer analyzer = new StandardAnalyzer();
//Analyzer analyzer = new CJKAnalyzer();
//Analyzer analyzer = new SmartChineseAnalyzer();
Analyzer analyzer = new IKAnalyzer();
// 获得tokenStream对象
// 第一个参数:域名,可以随便给一个
// 第二个参数:要分析的文本内容
//TokenStream tokenStream = analyzer.tokenStream("test",
//"The Spring Framework provides a comprehensive programming and configuration model.");
TokenStream tokenStream = analyzer.tokenStream("test","高富帅可以用二维表结构来逻辑表达实现的数据");
// 添加一个引用,可以获得每个关键词
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
// 添加一个偏移量的引用,记录了关键词的开始位置以及结束位置
OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
// 将指针调整到列表的头部
tokenStream.reset();
// 遍历关键词列表,通过incrementToken方法判断列表是否结束
while (tokenStream.incrementToken()) {
// 关键词的起始位置
System.out.println("start->" + offsetAttribute.startOffset());
// 取关键词
System.out.println(charTermAttribute);
// 结束位置
System.out.println("end->" + offsetAttribute.endOffset());
}
tokenStream.close();
}

5.IKAnalyzer分词

5.1IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext.dic;</entry> <!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>

 5.2扩展ext.dic

高富帅
二维表

5.3停止stopword.dic









a
an
and
are
as
at
be
but
by
for
if
in
into
is
it
no
not
of
on
or
such
that
the
their
then
there
these
they
this
to
was
will
with

6.封装LuceneHelper

package com.mf.lucene;

import java.io.File;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer; public class LuceneHelper { public IndexWriter getIndexWriter() throws Exception {
Directory directory = FSDirectory.open(new File("D:\\JavaWeb\\Lucene"));
// Directory directory = new RAMDirectory();//保存索引到内存中 (内存索引库)
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,
analyzer);
return new IndexWriter(directory, config);
}
//全删除
@Test
public void testAllDelete() throws Exception {
IndexWriter indexWriter = getIndexWriter();
indexWriter.deleteAll();
indexWriter.close();
}
//根据条件删除
@Test
public void testDelete() throws Exception {
IndexWriter indexWriter = getIndexWriter();
Query query = new TermQuery(new Term("title","c#"));
indexWriter.deleteDocuments(query);
indexWriter.close();
}
//修改
@Test
public void testUpdate() throws Exception {
IndexWriter indexWriter = getIndexWriter();
Document doc = new Document();
doc.add(new TextField("fileN", "测试文件名",Store.YES));
doc.add(new TextField("fileC", "测试文件内容",Store.YES));
indexWriter.updateDocument(new Term("isbn","9787115155108"), doc, new IKAnalyzer());
indexWriter.close();
}
//IndexReader IndexSearcher
public IndexSearcher getIndexSearcher() throws Exception{
// 第一步:创建一个Directory对象,也就是索引库存放的位置。
Directory directory = FSDirectory.open(new File("D:\\JavaWeb\\Lucene"));// 磁盘
// 第二步:创建一个indexReader对象,需要指定Directory对象。
IndexReader indexReader = DirectoryReader.open(directory);
// 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
return new IndexSearcher(indexReader);
}
//执行查询的结果
public void printResult(IndexSearcher indexSearcher,Query query)throws Exception{
// 第五步:执行查询。
TopDocs topDocs = indexSearcher.search(query, 10);
// 第六步:返回查询结果。遍历查询结果并输出。
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
int doc = scoreDoc.doc;
Document document = indexSearcher.doc(doc);
// 文件名称
String title = document.get("title");
System.out.println(title);
//WordsCount
String WordsCount = document.get("WordsCount");
System.out.println(WordsCount);
System.out.println("------------");
}
}
//查询所有
@Test
public void testMatchAllDocsQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
Query query = new MatchAllDocsQuery();
System.out.println(query);
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
//根据数值范围查询
@Test
public void testNumericRangeQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
Query query = NumericRangeQuery.newLongRange("WordsCount", 0L, 10000L, true, true);
System.out.println(query);
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
//可以组合查询条件
@Test
public void testBooleanQuery() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
BooleanQuery booleanQuery = new BooleanQuery();
Query query1 = new TermQuery(new Term("title","c#"));
Query query2 = new TermQuery(new Term("WordsCount","660000"));
// select * from user where id =1 or name = 'safdsa'
booleanQuery.add(query1, Occur.MUST);
booleanQuery.add(query2, Occur.MUST);
System.out.println(booleanQuery);
printResult(indexSearcher, booleanQuery);
//关闭资源
indexSearcher.getIndexReader().close();
}
//条件解释的对象查询
@Test
public void testQueryParser() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
//参数1: 默认查询的域
//参数2:采用的分析器
QueryParser queryParser = new QueryParser("title",new IKAnalyzer());
// *:* 域:值
Query query = queryParser.parse("title:c#");
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
}
//条件解析的对象查询 多个默念域
@Test
public void testMultiFieldQueryParser() throws Exception {
IndexSearcher indexSearcher = getIndexSearcher();
String[] fields = {"title","isbn"};
//参数1: 默认查询的域
//参数2:采用的分析器
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields,new IKAnalyzer());
// *:* 域:值
Query query = queryParser.parse("c#");
printResult(indexSearcher, query);
//关闭资源
indexSearcher.getIndexReader().close();
} }

Lucene之Java实战的更多相关文章

  1. 「小程序JAVA实战」springboot的后台搭建(31)

    转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...

  2. Java实战:教你如何进行数据库分库分表

    摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...

  3. 添物零基础到大型全栈架构师 Java实战及解析(实战篇)- 概述

    ​ 实战篇是在基础之上,进一步提升的内容.通过实战篇可以深入理解Java相关框架和库的使用,能够独立开发小模块,或者按照架构师的指导进行代码编写和完善. 主要讲解核心框架和库的使用和使用场景介绍.通过 ...

  4. java实战之解析xml

    在java中解析xml有现成的包提供方法,常用的有四类:Dom,JDom,Sax以及Dom4j.其中前者是java中自带的,后三者需要大家从开源诸如sourceforge这样的网站下载jar包,然后在 ...

  5. Java归去来第4集:java实战之Eclipse中创建Maven类型的SSM项目

    一.前言 如果还不了解剧情,请返回第3集的剧情          Java归去来第3集:Eclipse中给动态模块升级 二.在Eclipse中创建Maven类型的SSM项目 2.1:SSM简介 SSM ...

  6. Windows系统环境下Solr之Java实战(一)搭建solr服务器并配置IK分词

    搭建solr服务器 1.下载地址:http://archive.apache.org/dist/lucene/solr/ 2.将D:\JavaWeb\Solr\solr-6.2.0\server\so ...

  7. 【Java实战】源码解析Java SPI(Service Provider Interface )机制原理

    一.背景知识 在阅读开源框架源码时,发现许多框架都支持SPI(Service Provider Interface ),前面有篇文章JDBC对Driver的加载时应用了SPI,参考[Hibernate ...

  8. 使用Lucene的java api 写入和读取索引库

    import org.apache.commons.io.FileUtils;import org.apache.lucene.analysis.standard.StandardAnalyzer;i ...

  9. Zookeeper API for JAVA实战与应用

    package com.zookeeper.watcher; import java.util.List; import java.util.concurrent.CountDownLatch; im ...

随机推荐

  1. 【最简单】不用ps也可以批量转换图片格式

    不废话直接开始~ 1.新建文件夹,把需要转换的图片放进去,如图: 2.文件夹里建一txt文本,重点来了!txt文本的内容,如果是jpg转为png,则输入“ren *.jpg *.png”,同理png转 ...

  2. 9th 学习博客:使用Codebloks实现C++的图形化界面

    使用开发工具codeblocks,添加ResEdit.exe这个控件,可以很方便地进行图形化编辑,这是在网上找得教程,实现的是最基本的在对话框内添加按钮,并实现单击响应在控制台输出相应的文字. mai ...

  3. 6th Alpha阶段的postmortem报告

    组名:好好学习(代组长发布)  会议重要内容记录: 1.  尝试在beta阶段实现的功能,与alpha阶段相比的优势 (1)更改软件现有的bug: 1)软件的账目只能输入,但是一旦发生失误却无法更改和 ...

  4. 【uoj#213】[UNR #1]争夺圣杯 单调栈+差分

    题目描述 给出一个长度为 $n$ 的序列,对于 $1\sim n$ 的每一个数 $i$ ,求这个序列所有长度为 $i$ 的子区间的最大值之和,输出每一个 $i$ 的答案模 $998244353$ 后异 ...

  5. Android CollapsingToolbarLayout

    第一次看到这种用户体验是在Google Play Store App的应用详情的Activity中. 大的Banner图,能第一时间吸引用户的眼球,用不一样的Banner大图更具个性化的展示内容.图总 ...

  6. 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化

    挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...

  7. easyui的datebox只显示年月

    要求点击easyui的datebox时只显示年月,隐藏日,之前百度了好多,发现有的好麻烦,有的使用没效果,也许自己没理解,改不了.最后老员工帮我搞定了,添加一个fomatter和一个parser函数就 ...

  8. 【BZOJ2118】墨墨的等式(最短路)

    [BZOJ2118]墨墨的等式(最短路) 题面 BZOJ 洛谷 题解 和跳楼机那题是一样的. 只不过走的方式从\(3\)种变成了\(n\)种而已,其他的根本没有区别了. #include<ios ...

  9. hdu5909 Tree Cutting 【树形dp + FWT】

    题目链接 hdu5909 题解 设\(f[i][j]\)表示以\(i\)为根的子树,\(i\)一定取,剩余节点必须联通,异或和为\(j\)的方案数 初始化\(f[i][val[i]] = 1\) 枚举 ...

  10. Windows + Ubuntu下JDK与adb/android环境变量配置完整教程

    假设JDK和android sdk路径分别如下: D:\Program Files\Java\jdkD:\android-sdk 1.JDK环境变量配置JAVA_HOME=D:\Program Fil ...