欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lucene-搜索过滤

程序员文章站 2022-05-15 16:03:51
...

1、使用过滤可以缩小搜索空间,把可能的搜索匹配结果限制在所有文档的一个子集中。

2、内置了三个Filter子类:

1)DateFilter使搜索只限于指定的日期域的值在某一时间范围内的文档空间里

2)QueryFilter把查询结果做为另一个新查询可搜索的文档空间

3)CachingWrappperFilter是其他过滤器的装饰器,将结果缓存起来以便再次使用,从而提高性能。

3、DateFiler

此过滤器仅过滤,但不能缓存,如果重复使用DateFilter,Lucene每次都会重新进行日期过滤.导致性能下降.

下例中modified域索引为Keyword

public class FilterTest extends testcase{

privateQuery allBooks;

privateIndexsearcher searcher;

privateint numAllBooks;

protectedvoid setUp() throws Exception{

super.setUp();

allBooks=new RangeQuery(new Term("pubmonth","190001"),newTerm("pubmonth","200512"),true);

searcher=new IndexSearcher(directory);

Hits hits=searcher.search(allBooks);

numAllBooks=hits.length();
}

 

publicvoid testDateFilter() throws Exception{

Datejan1=parseDate("2004 Jan 01");

Date jan31=parseDate("2004 Jan 31");

Date dec31=parseDate("2004 Dec 31");

//过滤指定日期范围

DateFilter filter=new DateFilter("modified",jan1,dec31);

Hits hits=searcher.search(allBooks,filter);

assertEquals("all modified in 2004",numAllBooks,hits.length());

//过滤某一端日期边界不确定,使用静态方法

filter=DateFilter.Before("modified",jan31);//在jan31结束的结果

filter=DateFilter.After("modified",jan31);//从jan31开始的结果

}

}

4、QueryFilter

提供缓存功能,做为过滤结果将被缓存起来,以后使用同一个QueryFilter对象或IndexSearcher对象进行搜索时,优化性能。

public void testQueryFilter() throwsException{

TermQuery categoryQuery=new TermQuery(newTerm("category","/philosophy/eastern"));

FiltercategoryFilter=newQueryFilter(categoryQuery);

Hits hits=searcher.search(allBooks,categoryFilter);

}

下面使用QueryFilter完成DateFilter功能,并且具有缓存功能

public voidtestQueryFilterRange() throws Exception{

Date jan1=parseDate("2004 Jan01");//返回date对象;

Date dec31=parseDate("2004 Dec 31");

Termstart=newTerm("modified",DateField.dateToString(jan1));

Termend=newTerm("modified",DateField.dateToString(dec31));

 

QueryrangeQuery=new RangeQuery(start,end,true);

Filter filter=newQueryFilter(rangeQuery);

Hits hits=searcher.search(allBooks,filter);
}

下面使用QueryFilter完成通过过滤器使搜索结果文档限定在指定范围内

public void testrangefilter throwsException{

directory=new RAMDirectory();

setUp();

TermQuery query=new TermQuery(new Term("kword","info"));

IndexSearcher searcher=new IndexSearcher(directory);

Hitshits=searcher.search(query);//所以kword域含info的文档

QueryFilter jakeFilter=new QueryFilter(new TermQuery(newTerm("owner","jake")));

hits=searcher.search(query,jakeFilter);//所有owner域为jake的且kword域含info的文档

 

}

5、QueryFilter的替代方案

public void testFilter throws Exception{

TermQuery categoryQuery=newTermQuery(new Term("category","/philosophy/eastern"));

BooleanQuery conQuery=newBooleanQuery();

conQuery.add(allBooks,true,false);

conQuery.add(categoryQuery,true,false);

Hitshits=searcher.search(con1uery);

 

}

6、缓存过滤器结果

对于某此不具有缓存功能的过滤器来说,将它们馐到CachingWrapperFilter中后,Lucene会自动对非缓存过滤器的结果进行缓存(没有被引用的条目会被垃圾收集器清理)。

使用同一个IndexReader实例是使用过滤器缓存的关键。当索引的改变需要体现在搜索过程中时,就需要丢弃原来创建的IndexSearcher实现和IndexReader实例,将它们重新实例化

public void testcachingWrappper() throwsException{

Date jan1=parseDate("2004 Jan 01");

Date dec31=parseDate("2004Dec31");

DateFilter datefilter=new DateFiler("modified",jan1,dec31);

cachingFilter=new CachingWrapperFilter(datefilter);

Hits hits=searcher.search(allBooks,cachingFilter);

}

7、其他非内置的过滤器,在SandBox工具包中提供

1)ChainedFilter组成复杂的过滤器链。

2)FilteredQuery可以对某个查询进行过滤,因为在BooleanQuery对象中,它可做为一个单独查询子句,在不表示查询子句时,它又跟普通的search(Query,Filter)方法所具备的功能是一样的

相关标签: lucene