id
,订单号,身份证号这些是不用分词的,这个是必须全局匹配才会找到相关的内容id
,图片的路径等这个是不需要作为查询条件的,因此不需要索引
Document
中获取。 Document
中获取的Field
都要存储。Document
获取
IKAnalyzer
这个中文分词器<!-- 添加lucene支持 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.3</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.3</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>4.10.3</version>
</dependency>
<!-- IK分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
src/main/resource
路径下即可/**
* Lucene的工具类
* @author chenjiabing
*/
public class LuceneUtils {
/**
* 获取IndexWriter 用于创建索引库
* @return IndexWriter对象
* @throws Exception
*/
public static IndexWriter getIndexWriter() throws Exception{
//创建索引库存放的位置
Directory directory=FSDirectory.open(new File("/home/chenjiabing/Documents/Lucene"));
//使用IK中文分词器
IKAnalyzer ikAnalyzer=new IKAnalyzer(true);
//创建IndexWriteConfig对象,其中传入的是分析器对象
IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LATEST, ikAnalyzer);
//创建索引,其中的变量是索引库的位置,索引配置对象
IndexWriter indexWriter=new IndexWriter(directory, indexWriterConfig);
return indexWriter;
}
/**
* 获取IndexSearcher,用于查询
* @return IndexSearcher对象
* @throws Exception
*/
public static IndexSearcher getIndexSearcher()throws Exception{
//创建Directory对象,指定索引库的位置
Directory directory=FSDirectory.open(new File("/home/chenjiabing/Documents/Lucene"));
//创建IndexReader对象
IndexReader indexReader=DirectoryReader.open(directory);
//创建IndexSearcher对象
IndexSearcher indexSearcher=new IndexSearcher(indexReader);
return indexSearcher;
}
/**
* 根据查询语句,打印结果
* @param indexSearcher IndexSearch对象
* @param query 查询对象
* @param n 显示结果数量
* @throws IOException
*/
public static void doSearch(IndexSearcher indexSearcher,Query query,Integer n) throws IOException{
//执行查询
TopDocs topDocs=indexSearcher.search(query, n);
//返回查询结果
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
//遍历查询结果
for (ScoreDoc scoreDoc : scoreDocs) {
int doc=scoreDoc.doc; //返回文档的编号
//根据编号查询文档
Document document=indexSearcher.doc(doc);
//输出文档中定义的域
System.out.println(document.get("fileName"));
/*System.out.println(document.get("fileSize"));
System.out.println(document.get("fileContent"));
System.out.println(document.get("filePath"));*/
}
}
}
// 创建索引
@Test
public void testIndex() throws Exception {
IndexWriter indexWriter=LuceneUtils.getIndexWriter();
//创建File对象,这里是需要索引的文件
File file=new File("/home/chenjiabing/Documents/Blog");
//获取文件夹下的所有文件
File[] files=file.listFiles();
//遍历所有的文件,取出相关 的内容
for (File f : files) {
Document document=new Document(); //创建文档对象
//获取文件名
String fileName=f.getName();
//创建域 文件名 分词,索引 存储
Field fieldName=new TextField("fileName", fileName, Store.YES);
//获取文件大小
Long fileSize=FileUtils.sizeOf(f);
//创建文件大小的域,分词,索引,存储
Field fieldSize=new LongField("fileSize", fileSize, Store.YES);
//获取文件路径
String filePath=f.getPath();
//创建文件路径的域 不分词,不索引 但是必须存储,用来找到指定的文件
Field fieldPath=new StoredField("filePath", filePath);
//获取文件内容
String fileContent=FileUtils.readFileToString(f);
//创建文件内容的域,分词,索引,存储
Field fieldContent=new TextField("fileContent", fileContent,Store.YES);
//将分出的这些域添加到文档中
document.add(fieldContent);
document.add(fieldName);
document.add(fieldPath);
document.add(fieldSize);
//将文档写入索引库
indexWriter.addDocument(document);
}
//关闭IndexWriter对象
indexWriter.close();
}
TermQuery
项查询,TermQuery不使用分析器
,搜索关键词作为整体来匹配Field域中的词进行查询,比如订单号、分类ID号等。
springmvc拦截器
,那么只有当名称为...springmvc拦截器.....
这样整个词语连接在一起的时候才会查询到`TermQuery(new Term("域名","搜索的词语"))
: 这里的域名是创建Field的时候指定的:new Field("域名",值)
@Test
public void testTermQuerySearch() throws Exception{
//获取IndexSearcher
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
//创建一个TermQuery对象,指定查询的域和需要查询的词
TermQuery query=new TermQuery(new Term("fileName","springmvc拦截器"));
System.out.println(query);
//打印查询结果
LuceneUtils.doSearch(indexSearcher, query, 10);
//关闭IndexReader
indexSearcher.getIndexReader().close();
}
@Test
public void testNumericRangeQuery() throws Exception{
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
/**
* 这里是查询文件大小的域:fileSize
* 第一个参数: 域名
* 第二个参数:最小值
* 第三个参数: 最大值
* 第四个参数: 是否包含最小值
* 第五个参数: 是否包含最大值
*/
Query query=NumericRangeQuery.newLongRange("fileSize", 1000L, 2000L, true, true);
//输出查询条件:fileSize:[1000 TO 2000]
System.out.println(query);
LuceneUtils.doSearch(indexSearcher, query, 10);
//关闭IndexReader
indexSearcher.getIndexReader().close();
}
Occur.MUST
: 当前的查询条件必须满足Occur.SHOULD
: 当前的查询条件可满足可不满足,相当于or
MUST_NOT
:查询条件不能满足,相当于NOT
非+ @Test
public void testBooleanQuery() throws Exception{
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
//第一个查询条件 根据fileName域查询
Query query1=new TermQuery(new Term("fileName", "springmvc"));
//第二个查询条件,根据fileSize查询
Query query2=NumericRangeQuery.newLongRange("fileSize", 1000L, 2000L, true, true);
//创建BooleanQuery
BooleanQuery query=new BooleanQuery();
//添加查询条件,这个条件是必须满足的 :Occur.MUST
query.add(query1,Occur.MUST);
//添加第二个查询条件,这个条件可满足可不满足,相当于or
query.add(query2,Occur.SHOULD);
System.out.println(query);
//执行查询
LuceneUtils.doSearch(indexSearcher, query, 10);
indexSearcher.getIndexReader().close();
}
//查询所有
@Test
public void testMatchAllDoc() throws Exception{
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
Query query=new MatchAllDocsQuery();
System.out.println(query);
LuceneUtils.doSearch(indexSearcher, query, 10);
indexSearcher.getIndexReader().close();
}
QueryParser
也可以创建Query,QueryParser提供一个Parse
方法,此方法可以直接根据查询语法来查询 @Test
public void testQueryParser() throws Exception{
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
/**
* 第一个参数:指定了默认的查询的域名
* 第二个参数: 指定了分词器
*/
QueryParser parser=new QueryParser("fileName",new IKAnalyzer());
/**
* 其中的字符串的形式为: *:*
* 查询所有: *:*
* 根据默认域名查询直接写一个查询内容即可: "springmvc"
* 根据指定域名查询: "fileContent:springmvc"
*/
Query query=parser.parse("fileContent:拦截器");
System.out.println(query);
LuceneUtils.doSearch(indexSearcher, query, 50);
indexSearcher.getIndexReader().close();
}
@Test
public void testMulitFiledQueryParser() throws Exception{
IndexSearcher indexSearcher=LuceneUtils.getIndexSearcher();
//指定默认查询的域名
String[] fields={"fileName","fileContent"};
/**
* 创建对象
* 第一个参数: 指定默认域名的数组
* 第二参数: 指定分词器,这里使用中文分词器
*/
MultiFieldQueryParser parser=new MultiFieldQueryParser(fields, new IKAnalyzer());
//这里没有指定域名,因此使用上面指定的两个默认的域名进行查询,这两个默认域名之间是or关系,只要满足就查询返回
//Query query=parser.parse("springmvc");
//指定filePath域名中搜索
Query query=parser.parse("filePath:/home/chenjiabing");
System.out.println(query);
LuceneUtils.doSearch(indexSearcher, query, 50);
indexSearcher.getIndexReader().close();
}
document
的增删改查indexWriter.addDocument(doc)
Term
项删除索引,满足条件的将全部删除。ID
来进行删除和修改操作的。writer.deleteDocuments(new Term("域名","值"));
@Test
public void deleteIndex() throws Exception {
// 创建分词器,标准分词器
Analyzer analyzer = new IKAnalyzer();
// 创建IndexWriter
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
analyzer);
Directory directory = FSDirectory
.open(new File("E:\\11-index\\hcx\\"));
// 创建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// Terms
writer.deleteDocuments(new Term("id", "1"));
writer.close();
}
// 删除索引
@Test
public void deleteIndex() throws Exception {
// 1、指定索引库目录
Directory directory = FSDirectory.open(new File("E:\\11-index\\0720"));
// 2、创建IndexWriterConfig
IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST,
new StandardAnalyzer());
// 3、 创建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// 4、通过IndexWriter来删除索引
// a)、删除全部索引
writer.deleteAll();
// 5、关闭IndexWriter
writer.close();
}
@Test
public void updateIndex() throws Exception {
// 创建分词器,标准分词器
Analyzer analyzer = new StandardAnalyzer();
// 创建IndexWriter
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
analyzer);
Directory directory = FSDirectory
.open(new File("E:\\11-index\\hcx\\"));
// 创建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// 第一个参数:指定查询条件
// 第二个参数:修改之后的对象
// 修改时如果根据查询条件,可以查询出结果,则将以前的删掉,然后覆盖新的Document对象,如果没有查询出结果,则新增一个Document
// 修改流程即:先查询,再删除,在添加
Document doc = new Document();
doc.add(new TextField("name", "lisi", Store.YES));
writer.updateDocument(new Term("name", "zhangsan"), doc);
writer.close();
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。