Lucene之模糊、精確、匹配、範圍、多條件查詢-yellowcong
阿新 • • 發佈:2019-01-10
Lucene的查詢方式很 豐富,對於數值型別的資料,採取TermRangeQuery的方式,對於String型別的,就可以採取TermQuery等,查詢方式了,可以通過採取合適的查詢方式,檢索到資料。Queryparser這個查詢方式包含了其他幾種查詢方式。
查詢方式
查詢方式 | 意義 |
---|---|
TermQuery | 精確查詢 |
TermRangeQuery | 查詢一個範圍 |
PrefixQuery | 字首匹配查詢 |
WildcardQuery | 萬用字元查詢 |
BooleanQuery | 多條件查詢 |
PhraseQuery | 短語查詢 |
FuzzyQuery | 模糊查詢 |
Queryparser | 萬能查詢(上面的都可以用這個來查詢到) |
案例
package com.yellowcong.demo;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
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.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
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.WildcardQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立時間:下午5:27:50<br/>
* 建立日期:2017年12月2日<br/>
* 機能概要:
*/
public class Demo4 {
private static List<Passage> psgList = null;
// 寫物件
private static IndexWriter writer = null;
public static void main(String[] args) throws Exception {
// 刪除 所有索引
deleteAll();
// 建立索引
index();
//精確String 型別查詢
getByTermQuery();
//範圍查詢
getByRange();
//字首匹配查詢
getByPrefix();
//萬用字元查詢
getByWildcard();
//短語查詢
getByPhrase();
//模糊查詢
getByFuzzy();
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:00:43<br/>
* 機能概要:精確查詢
* @throws Exception
*/
public static void getByTermQuery() {
System.out.println("-------------查詢使用者名稱為yellowcong的資料-------------");
//精確查詢,根據名稱來直接
Query query = new TermQuery(new Term("username", "yellowcong"));
//執行查詢
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:25:21<br/>
* 機能概要:範圍查詢
*/
public static void getByRange(){
//精確查詢
System.out.println("-------------查詢id在1-3的資料-------------");
//查詢前三條資料,後面兩個true,表示的是是否包含頭和尾
Query query = NumericRangeQuery.newIntRange("id", 1, 3, true, true);
//執行查詢
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:25:56<br/>
* 機能概要:字首查詢資料
*/
public static void getByPrefix(){
System.out.println("-------------查詢字首 郵箱 以z開頭的資料-------------");
//查詢字首 郵箱 以z開頭的資料
Query query = new PrefixQuery(new Term("email", "z"));
//執行查詢
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:29:55<br/>
* 機能概要:萬用字元查詢資料
*/
public static void getByWildcard(){
//萬用字元就更簡單了,只要知道“*”表示0到多個字元,而使用“?”表示一個字元就行了
System.out.println("-------------------查詢email 以 @qq結尾的資料--------------");
//查詢email 以 @qq結尾的資料
Query query = new WildcardQuery(new Term("email","*@qq.com"));
//執行查詢
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:43:43<br/>
* 機能概要:短語查詢,查詢中間有幾個單詞的那種
*/
public static void getByPhrase(){
System.out.println("------------查詢內容中,有I LOVE YOU 的資料---------------");
//短語查詢,但是對於中文沒有太多的用,其中查詢的時候還有
PhraseQuery query = new PhraseQuery();
//設定有幾跳,表示中間存在一個單詞
query.setSlop(1);
//查詢
query.add(new Term("content","i"));
//I XX you 就可以被查詢出來
query.add(new Term("content","you"));
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:49:14<br/>
* 機能概要:預設提供的模糊查詢對中文來說,沒有任何用
* @throws Exception
*/
public static void getByFuzzy() throws Exception{
System.out.println("-------------------------模糊查詢---------------");
FuzzyQuery query = new FuzzyQuery(new Term("username","zhangsan"));
excQuery(query);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:01:55<br/>
* 機能概要:查詢Query 將需要查詢的條件傳遞進來
* @param query
*/
public static void excQuery(Query query){
//查詢
IndexReader reader = null;
try {
reader = getIndexReader();
//獲取查詢資料
IndexSearcher searcher = new IndexSearcher(reader);
//檢索資料
TopDocs topDocs = searcher.search(query, 100);
for(ScoreDoc scoreDoc : topDocs.scoreDocs){
//湖區偶
Document doc = reader.document(scoreDoc.doc);
System.out.println(doc.get("id")+":"+doc.get("username")+":"+doc.get("email"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
coloseReader(reader);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:上午11:52:52<br/>
* 機能概要:關閉IndexReader
* @param reader
*/
private static void coloseReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
static {
psgList = new ArrayList<Passage>();
// 產生一堆資料
psgList.add(new Passage(1, "yellowcong" ,
"[email protected]", "逗比", 23 , "I LOVE YOU ", new Date()));
psgList.add(new Passage(2, "張三" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(3, "李四" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(4, "王五" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(5, "趙六" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
System.out.println("-------------------------新增的資料----------------------");
for(Passage psg:psgList){
System.out.println(psg.getId()+":"+psg.getUsername()+":"+psg.getEmail()+":"+psg.getContent());
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:43:57<br/>
* 機能概要:獲取IndexWriter 同一時間 ,只能開啟一個 IndexWriter,獨佔寫鎖 。內建執行緒安全機制。
*
* @return
* @throws Exception
*/
@SuppressWarnings("static-access")
public static IndexWriter getIndexWriter() throws Exception {
// 建立IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 判斷資源是否佔用
if (writer == null || !writer.isLocked(fs)) {
synchronized (Demo3.class) {
if (writer == null || !writer.isLocked(fs)) {
// 建立writer物件
writer = new IndexWriter(fs,
new IndexWriterConfig(Version.LUCENE_45, new StandardAnalyzer(Version.LUCENE_45)));
}
}
}
return writer;
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:46:36<br/>
* 機能概要:獲取到IndexReader 任意多個IndexReaders可同時開啟,可以跨JVM。
*
* @return
* @throws Exception
*/
public static IndexReader getIndexReader() throws Exception {
// 建立IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 獲取到讀
return IndexReader.open(fs);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午7:57:04<br/>
* 機能概要:刪除所有的索引
*/
public static void deleteAll() {
IndexWriter writer = null;
try {
// 獲取IndexWriter
writer = getIndexWriter();
// 刪除所有的資料
writer.deleteAll();
int cnt = writer.numDocs();
System.out.println("索引條數\t" + cnt);
// 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:37:22<br/>
* 機能概要:獲取索引目錄
*
* @return 目錄
*/
private static String getIndexPath() {
// 獲取索引的目錄
String path = Demo3.class.getClassLoader().getResource("index").getPath();
// 不存在就建立目錄
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path;
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:24:16<br/>
* 機能概要:關閉IndexWriter
*/
private static void coloseWriter(IndexWriter writer) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:26:15<br/>
* 機能概要:關閉IndexReader
*
* @param reader
*/
public static void closerReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:10:01<br/>
* 機能概要: 查詢資料
*
* @param key
* 查詢範圍
* @param val
* 值
*/
public static void search(String key, Object val) {
IndexReader reader = null;
try {
reader = getIndexReader();
IndexSearcher searcher = new IndexSearcher(reader);
// 精確查詢
Query query = null;
// 定義查詢條件
if (val instanceof Integer) {
// 後面的兩個true 表示的是 是否包含 上下的資料
query = NumericRangeQuery.newIntRange(key, Integer.parseInt(val.toString()),
Integer.parseInt(val.toString()), true, true);
} else {
query = new TermQuery(new Term(key, val.toString()));
}
// QueryParser paraser = new QueryParser(Version.LUCENE_45, key, new
// StandardAnalyzer(Version.LUCENE_45));
// Query query = paraser.parse(val);
// 獲取查詢到的Docuemnt
TopDocs topDocs = searcher.search(query, 500);
// 總共命中的條數
System.out.println(topDocs.totalHits);
for (ScoreDoc score : topDocs.scoreDocs) {
//
Document doc = searcher.doc(score.doc);
// 查詢到的結果
String username = doc.get("username");
System.out.println(username);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closerReader(reader);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午6:03:33<br/>
* 機能概要:建立索引
*/
public static void index() {
IndexWriter writer = null;
try {
// 1、獲取IndexWriter
writer = getIndexWriter();
// 2、建立索引
for (Passage psg : psgList) {
Document doc = new Document();
// IntField 不能直接檢索到,需要結合
doc.add(new IntField("id", psg.getId(), Field.Store.YES));
// 使用者String型別的欄位的儲存,StringField是隻索引不分詞
doc.add(new TextField("username", psg.getUsername(), Field.Store.YES));
// 主要對int型別的欄位進行儲存,需要注意的是如果需要對InfField進行排序使用SortField.Type.INT來比較,如果進範圍查詢或過濾,需要採用NumericRangeQuery.newIntRange()
doc.add(new IntField("age", psg.getAge(), Field.Store.YES));
// 對String型別的欄位進行儲存,TextField和StringField的不同是TextField既索引又分詞
doc.add(new TextField("content", psg.getContent(), Field.Store.NO));
doc.add(new StringField("keyword", psg.getKeyword(), Field.Store.YES));
doc.add(new StringField("email", psg.getEmail(), Field.Store.YES));
// 日期資料新增索引
doc.add(new LongField("addDate", psg.getAddDate().getTime(), Field.Store.YES));
// 3、新增文件
writer.addDocument(doc);
}
// 索引條數
int cnt = writer.numDocs();
System.out.println("索引條數\t" + cnt);
// 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
}
static class Passage {
private int id;
private String username;
private String email;
private String keyword;
private int age;
// 這個模擬的是文章
private String content;
private Date addDate;
public Passage(int id, String username, String email, String keyword, int age, String content, Date addDate) {
super();
this.id = id;
this.username = username;
this.email = email;
this.keyword = keyword;
this.age = age;
this.content = content;
this.addDate = addDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getAddDate() {
return addDate;
}
public void setAddDate(Date addDate) {
this.addDate = addDate;
}
}
}
執行結果
Queryparser
通過Queryparaser直接就可以將上面的方法都包攬了
常用匹配
@Test
public void searchByQueryPhase() throws ParseException{
IndexUtils utls = new IndexUtils();
//設定預設搜尋域,將預設搜尋域 設定在Content
QueryParser parse = new QueryParser(Version.LUCENE_35, "content",new StandardAnalyzer(Version.LUCENE_35));
// parse.setDefaultOperator(Operator.AND);//將空格預設 定義為AND
parse.setAllowLeadingWildcard(true);//設定第一個* 可以匹配
Query query = parse.parse("yellow");
//其中空格預設就是OR
query = parse.parse("yellow cong");
//改變搜尋域,搜尋域 為 name
query = parse.parse("name:yellow1");
//使用萬用字元 , 設定查詢類容為 以 y 開頭的資料
query = parse.parse("name:y*"); //其中* 不可以放在字串的首位
//將字串放在首位,預設情況下回報錯
query = parse.parse("email:*@yellow.com"); //其中我們可以更改 第一個通配值得功能
//其中 + - 表示有 和沒有 其中需要有空格 ,而且第一個+ 或者 - 需要放在第一個位置
query = parse.parse("- content: cong + i "); //這個表示的是content 中不含有 cong ,但是含有i
//匹配區間, 其中TO 必須是大寫的,還有有空格
query = parse.parse("id:[1 TO 4]"); //設定查詢的Id為 1-4
//開區間匹配
query = parse.parse("id:(1 TO 4)");
//匹配連起來的String
query = parse.parse("\"I like yellow cong\""); //這個是查詢的一個一個詞 ,匹配String
//匹配一個或者多個數據
query = parse.parse("\"I cong\"~2"); //表示中間含有一個單詞
//模糊查詢
query = parse.parse("name:yellow~");
//匹配數字,這個方法中沒有字元類容,所以需要自定義了
IndexReaderHelper.searchByQueryPhase(query, 10);
}
案例
package com.yellowcong.demo;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
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.QueryParser;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
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.WildcardQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立時間:下午5:27:50<br/>
* 建立日期:2017年12月2日<br/>
* 機能概要:
*/
public class Demo5 {
private static List<Passage> psgList = null;
// 寫物件
private static IndexWriter writer = null;
public static void main(String[] args) throws Exception {
// 刪除 所有索引
deleteAll();
// 建立索引
index();
QueryParser parser = getQueryParser();
//將空格預設 定義為AND
// parse.setDefaultOperator(Operator.AND);
//設定第一個* 可以匹配
parser.setAllowLeadingWildcard(true);
//精確String 型別查詢
System.out.println("-------------查詢使用者名稱為yellowcong的資料-------------");
//精確查詢,根據名稱來直接
Query query = parser.parse("username:yellowcong");
//執行查詢
excQuery(query);
//範圍查詢
System.out.println("-------------查詢id在1-3的資料-------------");
//查詢前三條資料,後面兩個true,表示的是是否包含頭和尾
//匹配區間, 其中TO 必須是大寫的,還有有空格
query = parser.parse("id:[1 TO 3]"); //設定查詢的Id為 1-4
//執行查詢
excQuery(query);
//字首匹配查詢
System.out.println("-------------查詢字首 郵箱 以z開頭的資料-------------");
//查詢字首 郵箱 以z開頭的資料
query = parser.parse("email:z*");
excQuery(query);
//萬用字元查詢
//萬用字元就更簡單了,只要知道“*”表示0到多個字元,而使用“?”表示一個字元就行了
System.out.println("-------------------查詢email 以 @qq結尾的資料--------------");
//查詢email 以 @qq結尾的資料
//需要設定 * 可以放在前面 QueryParser.setAllowLeadingWildcard(true);
//將字串放在首位,預設情況下回報錯
query = parser.parse("email:*@qq.com");
excQuery(query);
//短語查詢
System.out.println("------------查詢內容中,有I LOVE YOU 的資料---------------");
//短語查詢,但是對於中文沒有太多的用,其中查詢的時候還有
query =parser.parse("\"i you\"~2"); //表示中間含有一個單詞
excQuery(query);
//模糊查詢
System.out.println("-------------------------模糊查詢---------------");
query = parser.parse("username:zhangsan~");
excQuery(query);
}
private static QueryParser getQueryParser(){
QueryParser parser =new QueryParser(Version.LUCENE_45,"content", new StandardAnalyzer(Version.LUCENE_45));
return parser;
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:下午12:01:55<br/>
* 機能概要:查詢Query 將需要查詢的條件傳遞進來
* @param query
*/
public static void excQuery(Query query){
//查詢
IndexReader reader = null;
try {
reader = getIndexReader();
//獲取查詢資料
IndexSearcher searcher = new IndexSearcher(reader);
//檢索資料
TopDocs topDocs = searcher.search(query, 100);
for(ScoreDoc scoreDoc : topDocs.scoreDocs){
//湖區偶
Document doc = reader.document(scoreDoc.doc);
System.out.println(doc.get("id")+":"+doc.get("username")+":"+doc.get("email"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
coloseReader(reader);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月3日<br/>
* 建立時間:上午11:52:52<br/>
* 機能概要:關閉IndexReader
* @param reader
*/
private static void coloseReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
static {
psgList = new ArrayList<Passage>();
// 產生一堆資料
psgList.add(new Passage(1, "yellowcong" ,
"[email protected]", "逗比", 23 , "I LOVE YOU ", new Date()));
psgList.add(new Passage(2, "張三" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(3, "李四" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(4, "王五" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
psgList.add(new Passage(5, "趙六" ,
"[email protected]", "逗比", 23, "三炮", new Date()));
System.out.println("-------------------------新增的資料----------------------");
for(Passage psg:psgList){
System.out.println(psg.getId()+":"+psg.getUsername()+":"+psg.getEmail()+":"+psg.getContent());
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:43:57<br/>
* 機能概要:獲取IndexWriter 同一時間 ,只能開啟一個 IndexWriter,獨佔寫鎖 。內建執行緒安全機制。
*
* @return
* @throws Exception
*/
@SuppressWarnings("static-access")
public static IndexWriter getIndexWriter() throws Exception {
// 建立IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 判斷資源是否佔用
if (writer == null || !writer.isLocked(fs)) {
synchronized (Demo3.class) {
if (writer == null || !writer.isLocked(fs)) {
// 建立writer物件
writer = new IndexWriter(fs,
new IndexWriterConfig(Version.LUCENE_45, new StandardAnalyzer(Version.LUCENE_45)));
}
}
}
return writer;
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:46:36<br/>
* 機能概要:獲取到IndexReader 任意多個IndexReaders可同時開啟,可以跨JVM。
*
* @return
* @throws Exception
*/
public static IndexReader getIndexReader() throws Exception {
// 建立IdnexWriter
String path = getIndexPath();
FSDirectory fs = FSDirectory.open(new File(path));
// 獲取到讀
return IndexReader.open(fs);
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午7:57:04<br/>
* 機能概要:刪除所有的索引
*/
public static void deleteAll() {
IndexWriter writer = null;
try {
// 獲取IndexWriter
writer = getIndexWriter();
// 刪除所有的資料
writer.deleteAll();
int cnt = writer.numDocs();
System.out.println("索引條數\t" + cnt);
// 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午5:37:22<br/>
* 機能概要:獲取索引目錄
*
* @return 目錄
*/
private static String getIndexPath() {
// 獲取索引的目錄
String path = Demo3.class.getClassLoader().getResource("index").getPath();
// 不存在就建立目錄
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path;
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:24:16<br/>
* 機能概要:關閉IndexWriter
*/
private static void coloseWriter(IndexWriter writer) {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:26:15<br/>
* 機能概要:關閉IndexReader
*
* @param reader
*/
public static void closerReader(IndexReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午8:10:01<br/>
* 機能概要: 查詢資料
*
* @param key
* 查詢範圍
* @param val
* 值
*/
public static void search(String key, Object val) {
IndexReader reader = null;
try {
reader = getIndexReader();
IndexSearcher searcher = new IndexSearcher(reader);
// 精確查詢
Query query = null;
// 定義查詢條件
if (val instanceof Integer) {
// 後面的兩個true 表示的是 是否包含 上下的資料
query = NumericRangeQuery.newIntRange(key, Integer.parseInt(val.toString()),
Integer.parseInt(val.toString()), true, true);
} else {
query = new TermQuery(new Term(key, val.toString()));
}
// QueryParser paraser = new QueryParser(Version.LUCENE_45, key, new
// StandardAnalyzer(Version.LUCENE_45));
// Query query = paraser.parse(val);
// 獲取查詢到的Docuemnt
TopDocs topDocs = searcher.search(query, 500);
// 總共命中的條數
System.out.println(topDocs.totalHits);
for (ScoreDoc score : topDocs.scoreDocs) {
//
Document doc = searcher.doc(score.doc);
// 查詢到的結果
String username = doc.get("username");
System.out.println(username);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closerReader(reader);
}
}
/**
* 建立使用者:狂飆的yellowcong<br/>
* 建立日期:2017年12月2日<br/>
* 建立時間:下午6:03:33<br/>
* 機能概要:建立索引
*/
public static void index() {
IndexWriter writer = null;
try {
// 1、獲取IndexWriter
writer = getIndexWriter();
// 2、建立索引
for (Passage psg : psgList) {
Document doc = new Document();
// IntField 不能直接檢索到,需要結合
doc.add(new IntField("id", psg.getId(), Field.Store.YES));
// 使用者String型別的欄位的儲存,StringField是隻索引不分詞
doc.add(new TextField("username", psg.getUsername(), Field.Store.YES));
// 主要對int型別的欄位進行儲存,需要注意的是如果需要對InfField進行排序使用SortField.Type.INT來比較,如果進範圍查詢或過濾,需要採用NumericRangeQuery.newIntRange()
doc.add(new IntField("age", psg.getAge(), Field.Store.YES));
// 對String型別的欄位進行儲存,TextField和StringField的不同是TextField既索引又分詞
doc.add(new TextField("content", psg.getContent(), Field.Store.NO));
doc.add(new StringField("keyword", psg.getKeyword(), Field.Store.YES));
doc.add(new StringField("email", psg.getEmail(), Field.Store.YES));
// 日期資料新增索引
doc.add(new LongField("addDate", psg.getAddDate().getTime(), Field.Store.YES));
// 3、新增文件
writer.addDocument(doc);
}
// 索引條數
int cnt = writer.numDocs();
System.out.println("索引條數\t" + cnt);
// 提交事物
writer.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
coloseWriter(writer);
}
}
static class Passage {
private int id;
private String username;
private String email;
private String keyword;
private int age;
// 這個模擬的是文章
private String content;
private Date addDate;
public Passage(int id, String username, String email, String keyword, int age, String content, Date addDate) {
super();
this.id = id;
this.username = username;
this.email = email;
this.keyword = keyword;
this.age = age;
this.content = content;
this.addDate = addDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String userna