安全过滤器:限制匹配范围
下面的例子里面,有两个索引文档,两者在关键字域里面都包含info项,但是每个文档属于不同的所有者;如果不使用过滤器的话,我们会搜索召两个文档。考虑到安全性,这当然不是我们想要的结果,因此我们可以使用QueryWrapperFilter将搜索空间限制在某个用于所拥有的文档范围之内。
示例代码:
package com.tan.code;
import java.io.IOException;
import java.util.logging.Filter;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
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.IndexSearcher;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
public class SecurityFilterTest {
private IndexWriter indexWriter = null;
private IndexSearcher indexSearcher = null;
public void securityFilter() throws IOException {
//写入内存
Directory directory = new RAMDirectory();
indexWriter = new IndexWriter(directory, new IndexWriterConfig(
Version.LUCENE_43, new StandardAnalyzer(Version.LUCENE_43)));
Document document = new Document();
// LiMing
document.add(new StringField("id", "1", Store.YES));
document.add(new TextField("owner", "LiMing", Store.YES));
document.add(new TextField("keywords", "LiMing Info", Store.YES));
indexWriter.addDocument(document);
// TanWeiJie
document = new Document();
document.add(new StringField("id", "2", Store.YES));
document.add(new TextField("owner", "TanWeiJie", Store.YES));
document.add(new TextField("keywords", "TannWeiJie Info", Store.YES));
indexWriter.addDocument(document);
indexWriter.commit();
indexWriter.close();
IndexReader r = DirectoryReader.open(directory);
indexSearcher = new IndexSearcher(r);
// 不使用过滤器
TermQuery termQuery = new TermQuery(new Term("keywords", "info"));
System.out.println("不使用过滤器匹配到"
+ indexSearcher.search(termQuery, 10).totalHits + "个结果");
// 使用过滤器
QueryWrapperFilter limingfilter = new QueryWrapperFilter(new TermQuery(
new Term("owner", "liming"))); // 注意这里需要小写,使用Luke查看索引的時候就可以發現分詞器都把大寫轉換成小寫
System.out.println("使用过滤器匹配到"
+ indexSearcher.search(termQuery, limingfilter, 10).totalHits
+ "个结果");
}
}
测试代码:
@Test
public void test() throws IOException {
//fail("Not yet implemented");
SecurityFilterTest securityFilterTest=new SecurityFilterTest();
securityFilterTest.securityFilter();
}
输出结果:
不使用过滤器匹配到2个结果
使用过滤器匹配到1个结果
【参考《Lucene In Action》】