官方网站:http://lucene.apache.org/
此处使用Eclipse、jdk1.7和Lucene4.10.3
创建一个java工程,并导入jar包:
<properties>
<comment>IK Analyzer 扩展配置comment>
<entry key="ext_dict">ext.dic;entry>
<entry key="ext_stopwords">stopword.dic;entry>
properties>
路人甲
炮灰乙
加利敦大学
...
的
了
是
额
a
an
and
are
as
at
be
本例演示将某磁盘路径的所有文件创建索引存储到指定位置,查询指定文档时不再从原路径下逐个查找,而是利用索引库查询从而快速定位指定文档。
package cn.jpc;
import java.io.File;
import org.apache.commons.io.FileUtils;
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.LongField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
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 org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class IndexWriterTest {
public static void main(String[] args) throws Exception {
// 指定索引库存放的路径
Directory directory = FSDirectory.open(new File("F:\\pandownlaod\\index"));
// 索引库还可以存放到内存中
// Directory directory = new RAMDirectory();
// 创建一个IKAnalyzer分析器
Analyzer analyzer = new IKAnalyzer();
// 创建IndexWriterConfig对象
// 第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST
// 第二根参数:分析器对象
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
// 创建IndexWriter对象
IndexWriter indexWriter = new IndexWriter(directory, config);
// 原始文档的路径
File dir = new File("F:\\pandownlaod\\需要创建索引的资料");
for (File f : dir.listFiles()) {
// 文件名
String fileName = f.getName();
// 文件内容
String fileContent = FileUtils.readFileToString(f);
// 文件路径
String filePath = f.getPath();
// 文件的大小
long fileSize = FileUtils.sizeOf(f);
// 创建文件名域
// 第一个参数:域的名称
// 第二个参数:域的内容
// 第三个参数:是否存储
Field fileNameField = new TextField("filename", fileName, Store.YES);
// 文件内容域
Field fileContentField = new TextField("content", fileContent, Store.YES);
// 文件路径域(不分析、不索引、只存储)
Field filePathField = new StoredField("path", filePath);
// 文件大小域
Field fileSizeField = new LongField("size", fileSize, Store.YES);
// 创建document对象
Document document = new Document();
document.add(fileNameField);
document.add(fileContentField);
document.add(filePathField);
document.add(fileSizeField);
// 创建索引,并写入索引库
indexWriter.addDocument(document);
}
// 关闭indexwriter
indexWriter.close();
}
}
运行该程序,即可在指定的索引存储位置生成索引。
package cn.jpc;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
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 org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class AddIndex {
public static void main(String[] args) throws Exception {
// 索引库存放路径
Directory directory = FSDirectory.open(new File("F:\\pandownlaod\\index"));
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
// 创建一个indexwriter对象
IndexWriter indexWriter = new IndexWriter(directory, config);
// 创建一个Document对象
Document document = new Document();
// 向document对象中添加域。
// 不同的document可以有不同的域,同一个document可以有相同的域。
document.add(new TextField("filename", "新添加的文档", Store.YES));
document.add(new TextField("content", "新添加的文档的内容", Store.NO));
document.add(new TextField("content", "新添加的文档的内容第二个content", Store.YES));
document.add(new TextField("content1", "新添加的文档的内容要能看到", Store.YES));
// 添加文档到索引库
indexWriter.addDocument(document);
// 关闭indexwriter
indexWriter.close();
}
}
package cn.jpc;
import java.io.File;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
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.wltea.analyzer.lucene.IKAnalyzer;
public class IndexReaderTest {
public static void main(String[] args) throws Exception {
// 指定索引库存放的路径
Directory directory = FSDirectory.open(new File("F:\\pandownlaod\\index"));
// 创建indexReader对象
IndexReader indexReader = DirectoryReader.open(directory);
// 创建indexsearcher对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
// 1、TermQuery查询:指定要查询的域和要查询的关键词
// Query query = new TermQuery(new Term("filename", "spring"));
// 2、MatchAllDocsQuery查询:查询索引目录中的所有文档
// Query query = new MatchAllDocsQuery();
// 3、NumericRangeQuery查询:可以根据数值范围查询
// Query query = NumericRangeQuery.newLongRange("size", 100l, 1000l, true, false);
// 4、BooleanQuery查询:可以组合查询条件
// BooleanQuery query = new BooleanQuery();
// Query query1 = new TermQuery(new Term("filename", "spring"));
// Query query2 = new TermQuery(new Term("content", "apache"));
// query.add(query1, Occur.MUST);
// query.add(query2, Occur.MUST);
// 5、queryparser查询:根据一句话查找,对该句话分词
// QueryParser queryParser = new QueryParser("content",new IKAnalyzer());
// Query query = queryParser.parse("Lucene是java开发的");
// 可以指定默认搜索的域是多个
String[] fields = { "filename", "content" };
// 创建一个MulitFiledQueryParser对象
MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());
Query query = queryParser.parse("java和apache");
// 执行查询
System.out.println(query);
// 第一个参数是查询对象,第二个参数是查询结果返回的最大值
TopDocs topDocs = indexSearcher.search(query, 10);
// 查询结果的总条数
System.out.println("查询结果的总条数:" + topDocs.totalHits);
// 遍历查询结果
// topDocs.scoreDocs存储了document对象的id
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
// scoreDoc.doc属性就是document对象的id
// 根据document的id找到document对象
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("filename"));
// System.out.println(document.get("content"));
System.out.println(document.get("path"));
System.out.println(document.get("size"));
}
// 关闭indexreader对象
indexReader.close();
}
}
package cn.jpc;
import java.io.File;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class UpdateIndex {
public static void main(String[] args) throws Exception {
Directory directory = FSDirectory.open(new File("F:\\pandownlaod\\index"));
// Directory directory = new RAMDirectory();//保存索引到内存中 (内存索引库)
// Analyzer analyzer = new StandardAnalyzer();// 官方推荐
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);
// 创建一个Document对象
Document document = new Document();
// 向document对象中添加域。
// 不同的document可以有不同的域,同一个document可以有相同的域。
document.add(new TextField("filename", "需要更新的文档.txt", Store.YES));
document.add(new TextField("content",
"2013年11月18日 - Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。", Store.YES));
//将content域中有apache的所有文档替换成document
indexWriter.updateDocument(new Term("content", "apache"), document);
// 关闭indexWriter
indexWriter.close();
}
}
package cn.jpc;
import java.io.File;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class DeleteIndex {
// 删除索引
public static void main(String[] args) throws Exception {
Directory directory = FSDirectory.open(new File("F:\\pandownlaod\\index"));
// Directory directory = new RAMDirectory();//保存索引到内存中 (内存索引库)
Analyzer analyzer = new IKAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
IndexWriter indexWriter = new IndexWriter(directory, config);
// 创建一个查询条件
Query query = new TermQuery(new Term("filename", "spring"));
// 1、根据查询条件删除
// indexWriter.deleteDocuments(query);
//2、删除全部
indexWriter.deleteAll();
// 关闭indexwriter
indexWriter.close();
}
}
Field类 | 数据类型 | Analyzed是否分析 | Indexed是否索引 | Stored是否存储 | 说明 |
---|---|---|---|---|---|
StringField(FieldName, FieldValue,Store.YES)) | 字符串 | N | Y | Y或N | 这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等)。是否存储在文档中用Store.YES或Store.NO决定 |
LongField(FieldName, FieldValue,Store.YES) | Long型 | Y | Y | Y或N | 这个Field用来构建一个Long数字型Field,进行分析和索引,比如(价格)是否存储在文档中用Store.YES或Store.NO决定 |
StoredField(FieldName, FieldValue) | 重载方法,支持多种类型 | N | N | Y | 这个Field用来构建不同类型Field。不分析,不索引,但要Field存储在文档中 |
TextField(FieldName, FieldValue, Store.NO)或TextField(FieldName, reader) | 字符串或流 | Y | Y | Y或N | 如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略. |
直接双击打开:lukeall-4.10.3.jar
查询语句是有语法的:
域名+“:”+搜索的关键字
域名+“:”+[最小值 TO 最大值]
范围查询在lucene中不支持数值类型,支持字符串类型。在solr中支持数值类型。
1)+条件1 +条件2:两个条件之间是并且的关系and
2)+条件1 条件2:必须满足第一个条件,应该满足第二个条件
3)条件1 条件2:两个条件满足其一即可。
4)-条件1 条件2:必须不满足条件1,要满足条件2
Lucene索引查询结果默认按照相关度排序,相关度排序是查询结果按照与查询关键字的相关性进行排序,越相关的越靠前。比如搜索“Lucene”关键字,与该关键字最相关的文章应该排在前边。
在索引时对某个文档的Field域设置加权值高,在搜索时匹配到这个Field就可能排在前边。lucene在执行搜索时对某个域进行加权,在进行组合域查询时,匹配到加权值高的域最后计算的相关度得分就高。
在Java代码中操作也很简单,只在将field添加进document之前调用setBoost()方法设置权重即可,例:field. setBoost(100f);