Springboot集成lucene4.7

Lucene是一套用于全文检索和搜寻的开源程式库,一星期的研究实现了简单的基于cms新闻管理系统的全文搜索引擎,自己做笔记记录一下,个人理解可以把lucene当做一个文档型数据库:

首先先了解lucene:

  百科是这样说的:Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。

lucene常用类

 (1)IndexWriter 索引过程的核心组件。这个类负责创建新索引或者打开已有索引,以及向索引中添加、删除或更新索引文档的信息。可以把IndexWriter看做这样一个对象:提供针对索引文件的写入操作,但不能用于读取或搜索索引。IndexWriter需要开辟一定空间来存储索引,该功能可以由Directory完成。

 (2)Diretory索引存放的位置,它是一个抽象类,它的子类负责具体制定索引的存储路径。lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectory和RAMDirectory两个类。

(3)Analyzer 分析器,主要用于分析搜索引擎遇到的各种文本,Analyzer的工作是一个复杂的过程:把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语(停用词),这里说的无效词语如英文中的“of”、“the”,中文中的“的”、“地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率。分词的规则千变万化,但目的只有一个:按语义划分。这点在英文中比较容易实现,因为英文本身就是以单词为单位的,已经用空格分开;而中文则必须以某种方法将连成一片的句子划分成一个个词语。具体划分方法下面再详细介绍,这里只需了解分析器的概念即可。

// 定义分词器

// Analyzer analyzer = new IKAnalyzer();//分词器

//Analyzer analyzer = new SimpleAnalyzer(Version.LUCENE_47);// 简单分词器

// Analyzer analyzer3 = new CJKAnalyzer(VERSION);// 二元切分

Analyzer analyzer = new IKAnalyzer(true);// 语意分词  false关闭智能分词 (对分词的精度影响较大)

//Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);// 创建标准分词器

   (4)Document 文档 Document相当于一个要进行索引的单元,可以是文本文件、字符串或者数据库表的一条记录等等,一条记录经过索引之后,就是以一个Document的形式存储在索引文件,索引的文件都必须转化为Document对象才能进行索引。

     Document doc = new Document();

       Field content = null;

        Field title = null;

        Field createTime = null;

        Field type = null;

        doc.add(id);

        doc.add(content);

        doc.add(title);

        doc.add(createTime);

        doc.add(type);

(5)Field 一个Document可以包含多个信息域,比如一篇文章可以包含“标题”、“正文”等信息域,这些信息域就是通过Field在Document中存储的。选择field还是比较重要的:

是否分词(Tokenized)

是:对该field存储的内容进行分词,分词的目的,就是为了索引。

  比如:商品名称、商品描述、商品价格

否:不需要对field存储的内容进行分词,不分词,不代表不索引,而是将整个内容进行索引。

  比如:商品id

是否索引(Indexed)

是:将分好的词进行索引,索引的目的,就是为了搜索。

  比如:商品名称、商品描述、商品价格、商品id

否:不索引,也就是不对该field域进行搜索。

是否存储(Stored)

是:将field域中的内容存储到文档域中。存储的目的,就是为了搜索页面显示取值用的。

  比如:商品名称、商品价格、商品id、商品图片地址

否:不将field域中的内容存储到文档域中。不存储,则搜索页面中没法获取该field域的值。

  比如:商品描述,由于商品描述在搜索页面中不需要显示,再加上商品描述的内容比较多,所以就不需要进行存储。如果需要商品描述,则根据搜索出的商品ID去数据库中查询,然后显示出商品描述信息即可。

  根据开发需求选择不同的Filed类型:我找到的常用类型

(6)IndexSearcher 是lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具。

 (7)IndexReader打开一个Directory读取索引类。

  (8)Query 查询,抽象类,必须通过一系列子类来表述检索的具体需求,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。

这个也是比较重要的:查询的条件查询:

BooleanClause用于表示布尔查询子句关系的类,包括:BooleanClause.Occur.MUST,BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.SHOULD。有以下6种组合:

1.MUST和MUST:取得连个查询子句的交集。

2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。

3.MUST_NOT和MUST_NOT:无意义,检索无结果。

4.SHOULD与MUST、SHOULD与MUST_NOT:SHOULD与MUST连用时,无意义,结果为MUST子句的检索结果。与MUST_NOT连用时,功能同MUST。

5.SHOULD与SHOULD:意思是 or  表示“或”关系,最终检索结果为所有检索子句的并集。

对于多条件查询还有其他的一些实现类比如 MultiFieldQueryParser.parse()来创建一个Query有多个参数,比较简单查下api就能明白。

(9)QueryParser 解析用户的查询字符串进行搜索,是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。

  (10)TopDocs 根据关键字搜索整个索引库,然后对所有结果进行排序,取指定条目的结果。

  (11)TokenStream Token分词器Analyzer通过对文本的分析来建立TokenStreams(分词数据流)。TokenStream是由一个个Token(分词组成的数据流)。所以说Analyzer就代表着一个从文本数据中抽取索引词(Term)的一种策略。

 (12)AttributeSourceTokenStream即是从Document的域(field)中或者查询条件中抽取一个个分词而组成的一个数据流。TokenSteam中是一个个的分词,而每个分词又是由一个个的属性(Attribute)组成。对于所有的分词来说,每个属性只有一个实例。这些属性都保存在AttributeSource中,而AttributeSource正是TokenStream的父类。

1.依赖注入:

<!-- ik.中文分词器依赖-->

<dependency>

<groupId>com.janeluo</groupId>

<artifactId>ikanalyzer</artifactId>

<version>2012_u6</version>

</dependency>

<!-- lucene依赖 -->

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-highlighter</artifactId>

<version>4.7.2</version>

</dependency>

2.实现的增删改查:

package com.yunqi.cms.common;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.document.Field.Store;

import org.apache.lucene.document.StringField;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.DirectoryReader;

import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.index.IndexWriterConfig;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.search.BooleanClause.Occur;

import org.apache.lucene.search.BooleanQuery;

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.store.Directory;

import org.apache.lucene.store.FSDirectory;

import org.apache.lucene.util.Version;

import org.wltea.analyzer.lucene.IKAnalyzer;

import com.yunqi.cms.entity.Content;

import com.yunqi.cms.vo.ContentVO;

import com.yunqi.cms.vo.LuceneContentVO;

import com.yunqi.platform.common.page.PageList;

import com.yunqi.platform.utils.LocalDateTimeUtils;

import com.yunqi.platform.utils.SystemConfigure;

/**

*

* @ClassName: LuceneUtils 

* @Description: 全文检索

* @author yangqq

* @date 2019年6月15日 上午11:45:00 

* @version V1.0 

* @Copyright: 2019 www.yunqi.com Inc. All rights reserved.

*/

public class LuceneUtils {

// 定义分词器

// Analyzer analyzer = new IKAnalyzer();//分词器

//Analyzer analyzer = new SimpleAnalyzer(Version.LUCENE_47);// 简单分词器

// Analyzer analyzer3 = new CJKAnalyzer(VERSION);// 二元切分

Analyzer analyzer = new IKAnalyzer(true);// 语意分词  false关闭智能分词 (对分词的精度影响较大)

//Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_47);// 创建一个分词器

public String createIndex(Object t) throws IOException {

if (t == null) {

throw new RuntimeException("所传对象不可为空");

}

LuceneContentVO contentvo = new LuceneContentVO();

if (t instanceof LuceneContentVO) {

contentvo = (LuceneContentVO) t;

// 创建Document对象

Document doc = new Document();

// 获取每列数据

if (contentvo.getId() == null) {

throw new RuntimeException("新闻Id不可为空");

}

if (contentvo.getSiteId() == null) {

throw new RuntimeException("站点信息不存在");

}

if(contentvo.getTitle()==null){

throw new RuntimeException("所存内容名称不可为空");

}

if(contentvo.getType()==null){

throw new RuntimeException("文章所属类型不可为空");

}

Field content = null;

Field title = null;

Field createTime = null;

Field type = null;

        Field id = new StringField("id", contentvo.getId().toString(),Store.YES);//标题 StringField索引存储不分词 

title = new TextField("title",  contentvo.getTitle(), Store.YES);


//如果是普通新闻,Content内容不存储,title标题进行分词存储,医生内容的title不分词

        if(contentvo.getType().equals(CmsCommon.CMS_NEWS)){

content = new TextField("content", "",Store.YES);//内容 TextField索引存储分词 

        }else{

        if (contentvo.getContent() != null) {

content = new TextField("content", contentvo.getContent().toString(),Store.YES); 

} else {

content = new TextField("content", "",Store.YES); 

}

//title = new StringField("title", contentvo.getTitle(), Store.YES);

        }


if (contentvo.getCreateTime() != null) {

createTime = new StringField("createTime", LocalDateTimeUtils.formatDateTime(contentvo.getCreateTime()), Store.YES);

} else {

createTime = new StringField("createTime","", Store.YES);

}

type = new StringField("type", contentvo.getType(), Store.YES);

// 添加到Document中

doc.add(id);

doc.add(content);

doc.add(title);

doc.add(createTime);

doc.add(type);

if (contentvo.getSiteId() != null) {

String path = "";

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + contentvo.getSiteId() + "/lucence";

// 调用,创建索引库

this.write(doc, path);

} else {

throw new RuntimeException("站点信息不存在");

}

System.out.println("id:" + contentvo.getId().toString());

}

return "成功";

}

// 初始化索引

public void initcreate(List<LuceneContentVO> list, Integer siteId) throws IOException {

String path = "";

if (siteId != null) {

// 创建储存路径

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + siteId + "/lucence";

delFolder(path);

}

if (list.size() > 0) {

for (LuceneContentVO contentvo : list) {

if (contentvo.getSiteId() == null) {

throw new RuntimeException("站点信息不存在");

}

if (contentvo.getId() == null) {

throw new RuntimeException("新闻Id不可为空");

}

if(contentvo.getTitle()==null){

throw new RuntimeException("所存内容名称不可为空");

}

if(contentvo.getType()==null){

throw new RuntimeException("文章所属类型不可为空");

}

Field content = null;

Field title = null;

Field createTime = null;

Field type = null;

        Field id = new StringField("id", contentvo.getId().toString(),Store.YES);//标题 StringField索引存储不分词 

title = new TextField("title",  contentvo.getTitle(), Store.YES);

//如果是普通新闻,Content内容不存储,title标题进行分词存储,医生内容的title不分词

        if(contentvo.getType().equals(CmsCommon.CMS_NEWS)){

content = new TextField("content", "",Store.YES);//内容 TextField索引存储分词 

        }else{

        if (contentvo.getContent() != null) {

content = new TextField("content", contentvo.getContent().toString(),Store.YES); 

} else {

content = new TextField("content", "",Store.YES); 

}

        }


if (contentvo.getCreateTime() != null) {

createTime = new StringField("createTime", LocalDateTimeUtils.formatDateTime(contentvo.getCreateTime()), Store.YES);

} else {

createTime = new StringField("createTime","", Store.YES);

}

type = new StringField("type", contentvo.getType(), Store.YES);

// 创建Document对象

Document doc = new Document();

// 给title加权

//title.setBoost(4f);

// 添加到Document中

doc.add(id);

doc.add(content);

doc.add(title);

doc.add(createTime);

doc.add(type);

Directory directory = null;

IndexWriterConfig config = null;

IndexWriter iwriter = null;

try {

// 索引库的存储目录()

directory = FSDirectory.open(new File(path));

// 关联当前lucence版本和分值器

config = new IndexWriterConfig(Version.LUCENE_47, analyzer);

// 传入目录和分词器

iwriter = new IndexWriter(directory, config);

iwriter.commit();

// 写入到目录文件中

iwriter.addDocument(doc);

// 提交事务

iwriter.commit();

// 关闭流

iwriter.close();

} catch (IOException e) {

e.printStackTrace();

} finally {

// 关闭流

iwriter.close();

}

}

}

}

// 删除指定文件夹下所有文件

// param path 文件夹完整绝对路径

public static boolean delAllFile(String path) {

boolean flag = false;

File file = new File(path);

if (!file.exists()) {

return flag;

}

if (!file.isDirectory()) {

return flag;

}

String[] tempList = file.list();

File temp = null;

for (int i = 0; i < tempList.length; i++) {

if (path.endsWith(File.separator)) {

temp = new File(path + tempList[i]);

} else {

temp = new File(path + File.separator + tempList[i]);

}

if (temp.isFile()) {

temp.delete();

}

if (temp.isDirectory()) {

delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件

delFolder(path + "/" + tempList[i]);// 再删除空文件夹

flag = true;

}

}

return flag;

}

// 删除文件夹

// param folderPath 文件夹完整绝对路径

public static void delFolder(String folderPath) {

try {

delAllFile(folderPath); // 删除完里面所有内容

String filePath = folderPath;

filePath = filePath.toString();

java.io.File myFilePath = new java.io.File(filePath);

myFilePath.delete(); // 删除空文件夹

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 封裝一个方法,将关键字词存储到索引文件中

*

* @param doc

* @throws IOException

*/

public void write(Document doc, String dir) throws IOException {

Directory directory = null;

IndexWriterConfig config = null;

IndexWriter iwriter = null;

try {

// 索引库的存储目录

directory = FSDirectory.open(new File(dir));

// 关联当前lucence版本和分值器

config = new IndexWriterConfig(Version.LUCENE_47, analyzer);

// 传入目录和分词器

iwriter = new IndexWriter(directory, config);

iwriter.commit();

// 写入到目录文件中

iwriter.addDocument(doc);

// 提交事务

iwriter.commit();

} catch (IOException e) {

e.printStackTrace();

} finally {

// 关闭流

iwriter.close();

}

}

/**

* 修改

*

* @param Object

*/

public void updateDocument(Object t) throws IOException {

if (t == null) {

throw new RuntimeException("所传对象不可为空");

}

try {

LuceneContentVO contentvo = new LuceneContentVO();

if (t instanceof LuceneContentVO) {

contentvo = (LuceneContentVO) t;

if (contentvo.getId() == null) {

throw new RuntimeException("所传对象ID不可为空");

}

String path = "";

if (contentvo.getSiteId() != null) {

// 创建储存路径

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + contentvo.getSiteId() + "/lucence";

}

// 创建Document对象

Document doc = new Document();

if (contentvo.getSiteId() == null) {

throw new RuntimeException("站点信息不存在");

}

if (contentvo.getId() == null) {

throw new RuntimeException("新闻Id不可为空");

}

if(contentvo.getTitle()==null){

throw new RuntimeException("所存内容名称不可为空");

}

if(contentvo.getType()==null){

throw new RuntimeException("文章所属类型不可为空");

}

Field content = null;

Field title = null;

Field createTime = null;

Field type = null;

        Field id = new StringField("id", contentvo.getId().toString(),Store.YES);//标题 StringField索引存储不分词 

title = new TextField("title",  contentvo.getTitle(), Store.YES);

//如果是普通新闻,Content内容不存储,title标题进行分词存储,医生内容的title不分词

        if(contentvo.getType().equals(CmsCommon.CMS_NEWS)){

content = new TextField("content", "",Store.YES);//内容 TextField索引存储分词 

        }else{

        if (contentvo.getContent() != null) {

content = new TextField("content", contentvo.getContent().toString(),Store.YES); 

} else {

content = new TextField("content", "",Store.YES); 

}

//title = new StringField("title", contentvo.getTitle(), Store.YES);

        }


if (contentvo.getCreateTime() != null) {

createTime = new StringField("createTime", LocalDateTimeUtils.formatDateTime(contentvo.getCreateTime()), Store.YES);

} else {

createTime = new StringField("createTime","", Store.YES);

}

type = new StringField("type", contentvo.getType(), Store.YES);

// 添加到Document中

doc.add(id);

doc.add(content);

doc.add(title);

doc.add(createTime);

doc.add(type);

this.deleteDocuments(contentvo.getId(), contentvo.getSiteId(),contentvo.getType());

this.write(doc, path);

System.out.println("contentId:" + contentvo.getId().toString());

}

} catch (Exception e) {

e.printStackTrace();

}

}

// 根据名称和类型分页搜索

public PageList<ContentVO> searchPage(Content content) throws IOException {

Directory directory = null;

DirectoryReader ireader = null;

PageList<ContentVO> pageList = new PageList<>();

List<ContentVO> cList = new ArrayList<>();

if (content == null) {

throw new RuntimeException("查询新闻信息不可为空");

}

int pageNow = content.getCurrentPage();

int pageSize = content.getPageSize();

try {

// 索引库的存储目录

String path = "";

if (content.getSiteId() != null) {

// 创建储存路径

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + content.getSiteId() + "/lucence";

}

directory = FSDirectory.open(new File(path));

// 读取索引库的存储目录

ireader = DirectoryReader.open(directory);

// 搜索类

IndexSearcher isearcher = new IndexSearcher(ireader);

//开始

BooleanQuery booleanQuery = new BooleanQuery();

// 条件一内容中必须要有title标题

QueryParser parser1 = new QueryParser(Version.LUCENE_47, "title", analyzer);

// 搜索

Query query1 = parser1.parse(content.getTitle());

booleanQuery.add(query1, Occur.SHOULD);

// 条件二内容中包含的词语

QueryParser parser2 = new QueryParser(Version.LUCENE_47, "content", analyzer);

Query query2 = parser2.parse(content.getTitle());

booleanQuery.add(query2, Occur.SHOULD);

TopDocs topDocs = isearcher.search(booleanQuery, pageSize * pageNow);

System.out.println("查询到的条数\t" + topDocs.totalHits);

ScoreDoc[] scores = topDocs.scoreDocs;

int start = (pageNow - 1) * pageSize;

int end = pageSize * pageNow;

if (topDocs.totalHits <= end) {

for (int i = start; i < topDocs.totalHits; i++) {

Document hitDoc = isearcher.doc(scores[i].doc);

ContentVO co = new ContentVO();

co.setId(Integer.parseInt(hitDoc.get("id")));

co.setContent(hitDoc.get("content"));

co.setTitle(hitDoc.get("title"));

co.setCreateTime(LocalDateTimeUtils.parseDateTime(hitDoc.get("createTime")));

co.setMediaType(hitDoc.get("type"));

cList.add(co);

}

} else {

for (int i = start; i < end; i++) {

Document hitDoc = isearcher.doc(scores[i].doc);

ContentVO co = new ContentVO();

co.setId(Integer.parseInt(hitDoc.get("id")));

co.setContent(hitDoc.get("content"));

co.setTitle(hitDoc.get("title"));

co.setCreateTime(LocalDateTimeUtils.parseDateTime(hitDoc.get("createTime")));

co.setMediaType(hitDoc.get("type"));

cList.add(co);

}

}

pageList.setList(cList);

pageList.setPageSize(content.getPageSize());

pageList.setCurrentPage(content.getCurrentPage());

pageList.setTotalSize(topDocs.totalHits);

return pageList;

} catch (Exception e) {

e.printStackTrace();

} finally {

ireader.close();

directory.close();

}

return pageList;

}

// 根据id和类型不分页搜索

public List<ContentVO> searchById(LuceneContentVO content) throws IOException {

Directory directory = null;

DirectoryReader ireader = null;

List<ContentVO> cList = new ArrayList<>();

if (content == null) {

throw new RuntimeException("查询新闻信息不可为空");

}

try {

// 索引库的存储目录

String path = "";

if (content.getSiteId() != null) {

// 创建储存路径

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + content.getSiteId() + "/lucence";

}

directory = FSDirectory.open(new File(path));

// 读取索引库的存储目录

ireader = DirectoryReader.open(directory);

// 搜索类

IndexSearcher isearcher = new IndexSearcher(ireader);

//开始

BooleanQuery booleanQuery = new BooleanQuery();

// 条件一内容中必须要有id

QueryParser parser1 = new QueryParser(Version.LUCENE_47, "id", analyzer);

// 搜索

Query query1 = parser1.parse(content.getId().toString());

// 条件二内容type属于医生或者普通新闻

QueryParser parser2 = new QueryParser(Version.LUCENE_47, "type", analyzer);

Query query2 = parser2.parse(content.getType());

//Query query2 = parser2.parse("Y");

booleanQuery.add(query1, Occur.MUST);

booleanQuery.add(query2, Occur.MUST);

TopDocs topDocs = isearcher.search(booleanQuery, 1000);

System.out.println("查询到的条数\t" + topDocs.totalHits);

ScoreDoc[] scores = topDocs.scoreDocs;

for (int i = 0; i < topDocs.totalHits; i++) {

Document hitDoc = isearcher.doc(scores[i].doc);

ContentVO co = new ContentVO();

co.setId(Integer.parseInt(hitDoc.get("id")));

co.setContent(hitDoc.get("content"));

co.setTitle(hitDoc.get("title"));

co.setCreateTime(LocalDateTimeUtils.parseDateTime(hitDoc.get("createTime")));

co.setMediaType(hitDoc.get("type"));

cList.add(co);

}

return cList;

} catch (Exception e) {

e.printStackTrace();

} finally {

ireader.close();

directory.close();

}

return cList;

}

/**

* 删除文档

*

* @throws IOException

*/

public void deleteDocuments(Integer id, Integer siteId,String type) throws IOException {

Directory directory = null;

IndexWriterConfig config = null;

IndexWriter iwriter = null;

try {

// 索引库的存储目录

String path = "";

if (siteId != null) {

// 创建储存路径

String resUploadPath = SystemConfigure.getValue("res_upload_path");

path = resUploadPath + siteId + "/lucence";

}

directory = FSDirectory.open(new File(path));

// 关联当前lucence版本和分值器

config = new IndexWriterConfig(Version.LUCENE_47, analyzer);

// 传入目录和分词器

iwriter = new IndexWriter(directory, config);

/*// 删除title中含有关键词“contentId”的文档

iwriter.deleteDocuments(new Term("id", id.toString()));

*/

//开始

BooleanQuery booleanQuery = new BooleanQuery();

// 条件一内容中必须要有id

QueryParser parser1 = new QueryParser(Version.LUCENE_47, "id", analyzer);

// 搜索

Query query1 = parser1.parse(id.toString());

// 条件二内容type属于医生或者普通新闻

QueryParser parser2 = new QueryParser(Version.LUCENE_47, "type", analyzer);

Query query2 = parser2.parse(type);

booleanQuery.add(query1, Occur.MUST);

booleanQuery.add(query2, Occur.MUST);

iwriter.deleteDocuments(booleanQuery);

iwriter.commit();

System.out.println("删除完成");

} catch (Exception e) {

e.printStackTrace();

} finally {

iwriter.close();

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • 目录结构:1.全文检索 2.Lucene入门3.Lucene进阶 全文检索 一, 生活中的搜索:1.Win...
    CoderZS阅读 1,671评论 0 12
  • 何为Lucene.Net? Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,...
    做全栈攻城狮阅读 1,054评论 0 0
  • 1. 案例分析:什么时全文检索,如何实现全文检索   1.1 案例   实现一个文件的搜索功能,通过关键字搜索文件...
    东方舵手阅读 1,180评论 0 1
  • 写在前面:本文中用到的 Apache Lucene 版本号是 4.10.2 截止到文章发布时官方的最新版本是 6....
    SawyerZh阅读 4,392评论 2 15
  • 12/26 今天听一位大咖分享,里面有提到: 若你做一件事,问问自己,你是不能做,而是不去做? 听过后,反思下自己...
    微风嘻嘻阅读 274评论 0 1