您的位置:首页 > 产品设计 > UI/UE

07-自定义QueryParer解决部分查询的性能问题/解决日期和数字范围问题

2015-04-20 17:47 423 查看
CustomParser.java

package org.itat.lucene.util;

import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.Version;

public class CustomParser extends QueryParser {

public CustomParser(Version matchVersion, String f, Analyzer a) {
super(matchVersion, f, a);
}

/**
*@MethodName:getWildcardQuery
*@Description:禁止通配符查询
*@param field
*@param termStr
*@throws ParseException
*@author:半仙儿
*@date:2015-4-20下午01:09:22
*/
@Override
protected org.apache.lucene.search.Query getWildcardQuery(String field,
String termStr) throws ParseException {
throw new ParseException("由于性能原因,已经禁用了通配符查询,请输入更精确的信息进行查询!");
}

/**
*@MethodName:getFuzzyQuery
*@Description:禁止模糊查询
*@param field
*@param termStr
*@param minSimilarity
*@throws ParseException
*@author:半仙儿
*@date:2015-4-20下午01:09:42
*/
@Override
protected org.apache.lucene.search.Query getFuzzyQuery(String field,
String termStr, float minSimilarity) throws ParseException {
throw new ParseException("由于性能原因,已经禁用了模糊查询,请输入更精确的信息进行查询!");
}

@Override
protected org.apache.lucene.search.Query getRangeQuery(String field,
String part1, String part2, boolean inclusive)
throws ParseException {
if (field.equals("size")) {
return NumericRangeQuery.newIntRange(field,
Integer.parseInt(part1), Integer.parseInt(part2),
inclusive, inclusive);
} else if (field.equals("date")) {
String dateType = "yyyy-MM-dd";
Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
if (pattern.matcher(part1).matches()
&& pattern.matcher(part2).matches()) {
SimpleDateFormat sdf = new SimpleDateFormat(dateType);
try {
long start = sdf.parse(part1).getTime();
long end = sdf.parse(part2).getTime();
return NumericRangeQuery.newLongRange(field, start, end, inclusive, inclusive);
} catch (Exception e) {
e.printStackTrace();
}
} else {
throw new ParseException("要检索的日期格式不正确,请使用" + dateType + "这种类型");
}
}
return this.newRangeQuery(field, part1, part2, inclusive);
}

}


CustomParserUtil.java
package org.itat.lucene.util;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
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.util.Version;

public class CustomParserUtil {
public void searcherByCustomQuery(String value) {
try {
IndexSearcher searcher = new IndexSearcher(IndexReader
.open(FileIndexUtil.getDirectory()));
TopDocs tds = null;
CustomParser parser = new CustomParser(Version.LUCENE_35,
"content", new StandardAnalyzer(Version.LUCENE_35));
Query queryStr = parser.parse(value);
tds = searcher.search(queryStr, 50);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document d = searcher.doc(sd.doc);
System.out.println(sd.doc + ":(" + sd.score + ")["
+ d.get("filename") + "[" + d.get("path") + "]-"
+ d.get("score") + "->" + d.get("size") + "----"
+ sdf.format(new Date(Long.valueOf(d.get("date"))))
+ "]");
}
searcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public void searcherByQuery(String value) {
try {
IndexSearcher searcher = new IndexSearcher(IndexReader
.open(FileIndexUtil.getDirectory()));
TopDocs tds = null;
CustomParser parser = new CustomParser(Version.LUCENE_35,
"content", new StandardAnalyzer(Version.LUCENE_35));
Query queryStr = parser.parse(value);
tds = searcher.search(queryStr, 50);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document d = searcher.doc(sd.doc);
System.out.println(sd.doc + ":(" + sd.score + ")["
+ d.get("filename") + "[" + d.get("path") + "]-"
+ d.get("score") + "->" + d.get("size") + "----"
+ sdf.format(new Date(Long.valueOf(d.get("date"))))
+ "]");
}
searcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}

}
FileIndexUtil.java
package org.itat.lucene.util;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
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;

public class FileIndexUtil {
private static Directory directory = null;
static {
try {
directory = FSDirectory.open(new File("d:/lucene/files"));
} catch (Exception e) {
e.printStackTrace();
}
}

public static Directory getDirectory() {
return directory;
}

/**
*@MethodName:index
*@Description:创建索引
*@param hasNew是否要新建索引
*@author:半仙儿
*@return void
*@date:2015-4-15下午04:05:04
*/
public static void index(boolean hasNew) {
IndexWriter writer = null;
try {
writer = new IndexWriter(directory, new IndexWriterConfig(
Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
if (hasNew) {
writer.deleteAll();
}
File file = new File("d:/lucene/example");
Document doc = null;

//定义一个随机数
Random ran=new Random();

for (File f : file.listFiles()) {
//分数
int score=ran.nextInt(600);

doc = new Document();
doc.add(new Field("content", new FileReader(f)));
doc.add(new Field("filename", f.getName(), Field.Store.YES,
Field.Index.NOT_ANALYZED));
doc.add(new Field("path", f.getAbsolutePath(), Field.Store.YES,
Field.Index.NOT_ANALYZED));
doc.add(new NumericField("date", Field.Store.YES, true)
.setLongValue(f.lastModified()));
doc.add(new NumericField("size", Field.Store.YES, true)
.setIntValue((int) f.length()));
doc.add(new NumericField("score",Field.Store.NO,true).setIntValue(score));
writer.addDocument(doc);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


SearchTest.java
package org.itat.lucene.util;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;

public class SearchTest {
// 高效获取indexReader
private static IndexReader reader = null;
static {
try {
reader = IndexReader.open(FileIndexUtil.getDirectory());
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public IndexSearcher getSeacher() {
try {
if (reader == null) {
reader = IndexReader.open(FileIndexUtil.getDirectory());
} else {
IndexReader tr = IndexReader.openIfChanged(reader);
if (tr != null) {
reader.close();
reader = tr;
}
}
return new IndexSearcher(reader);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

public void searcherByFilter(String queryStr, Filter filter) {
try {
IndexSearcher searcher = getSeacher();
QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
new StandardAnalyzer(Version.LUCENE_35));
Query query = parser.parse(queryStr);
TopDocs tds = null;
if (filter != null) {
tds = searcher.search(query, filter, 50);
} else {
tds = searcher.search(query, 50);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document d = searcher.doc(sd.doc);
System.out.println(sd.doc + ":(" + sd.score + ")["
+ d.get("filename") + "[" + d.get("path") + "]-->"
+ d.get("size") + "----"
+ sdf.format(new Date(Long.valueOf(d.get("date"))))
+ "]");
}
searcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public void searcherByQuery(Query queryStr) {
try {
IndexSearcher searcher = getSeacher();
TopDocs tds = null;
tds = searcher.search(queryStr, 50);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document d = searcher.doc(sd.doc);
System.out.println(sd.doc + ":(" + sd.score + ")["
+ d.get("filename") + "[" + d.get("path") + "]-->"
+ d.get("size") + "----"
+ sdf.format(new Date(Long.valueOf(d.get("date"))))
+ "]");
}
searcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public void searcherBySort(String queryStr, Sort sort) {
try {
IndexSearcher searcher = getSeacher();
QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
new StandardAnalyzer(Version.LUCENE_35));
Query query = parser.parse(queryStr);
TopDocs tds = null;
if (sort != null) {
tds = searcher.search(query, 50, sort);
} else {
tds = searcher.search(query, 50);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc sd : tds.scoreDocs) {
Document d = searcher.doc(sd.doc);
System.out.println(sd.doc + ":(" + sd.score + ")["
+ d.get("filename") + "[" + d.get("path") + "]-"+d.get("score")+"->"
+ d.get("size") + "----"
+ sdf.format(new Date(Long.valueOf(d.get("date"))))
+ "]");
}
searcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}


TestSearch.java
package org.itat.lucene.test;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.NumericRangeFilter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.WildcardQuery;
import org.itat.lucene.util.FileIndexUtil;
import org.itat.lucene.util.SearchTest;
import org.junit.Before;
import org.junit.Test;

public class TestSearch {
private SearchTest st;

@Before
public void init() {
st = new SearchTest();
}

@Test
public void index() {
FileIndexUtil.index(true);
}

@Test
public void test01() {
// 不进行排序
st.searcherBySort("java", Sort.INDEXORDER);
// 以Doc的Id进行排序
// st.searcherBySort("java", Sort.INDEXORDER);
// 通过评分进行排序--设置了排序,就不能看到评分了。
// st.searcherBySort("java", Sort.RELEVANCE);
// 根据文件的大小进行排序
// st.searcherBySort("java", new Sort(new SortField("size",
// SortField.INT)));
// 通过日期进行排序
// st.searcherBySort("java", new Sort(new SortField("date",
// SortField.LONG)));
// 通过文件名进行排序
// st.searcherBySort("java", new Sort(
// new SortField("filename", SortField.STRING)));
// 使用降序进行排序(通过设置SortField的最后的一个参数设置降序排序)
// st.searcherBySort("java", new Sort(new SortField("filename",
// SortField.STRING, true)));
// 根据文件的大小和评分进行排序
st.searcherBySort("java", new Sort(
new SortField("size", SortField.INT), SortField.FIELD_SCORE));

}

@Test
public void test02() {
Filter tr = new TermRangeFilter("filename", "java.hhh", "java.ttt",
true, true);
tr = NumericRangeFilter.newIntRange("size", 500, 4900, true, true);
//通过query进行过滤
tr = new QueryWrapperFilter(new WildcardQuery(new Term("filename",
"*.ff")));
st.searcherByFilter("java", tr);
}

@Test
public void test03() {
Query query = new WildcardQuery(new Term("filename", "c*"));
st.searcherByQuery(query);
}
}


TestCustomParser.java
package org.itat.lucene.test;

import org.itat.lucene.util.CustomParserUtil;
import org.junit.Test;

public class TestCustomParser {
@Test
public void test01() {
CustomParserUtil cpu = new CustomParserUtil();
// cpu.searcherByCustomQuery("java");
// cpu.searcherByCustomQuery("java~");
// cpu.searcherByCustomQuery("ja?va");
// cpu.searcherByQuery("size:[300 TO 4000]");
// cpu.searcherByQuery("content:[a TO j]");
// cpu.searcherByQuery("date:[2011-12-02 TO 2015-10-02]");
}
}
性能问题运行结果:





数字范围:



日期:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐