搜索引擎Lucene(5):搜索执行过程及搜索类型

1、搜索处理示例

public class Searcher {
    public static void search(String indexDir, String q) throws IOException, ParseException {
        // 得到读取索引文件的路径
        Directory dir = FSDirectory.open(Paths.get(indexDir));
        // 通过Dir得到路径下所有文件
        IndexReader reader = DirectoryReader.open(dir);
        // 建立索引查询器
        IndexSearcher searcher = new IndexSearcher(reader);
        // 实例化分析器
        Analyzer analyzer = new StandardAnalyzer();
        /********建立查询解析器********/
        // 第一个参数是要查询的字段; 第二个参数市分析器Analyzer
        String[] fields = {"name", "path"};
        Map fieldMap = new HashMap<>();
        fieldMap.put("name",100.0f);
        fieldMap.put("path",1.0f);
        QueryParser parser = new MultiFieldQueryParser(fields,new CJKAnalyzer());
        // 根据传进来的q查找
        Query query = parser.parse(q);
        // 计算索引开始时间
        long start = System.currentTimeMillis();
        /********开始查询********/
        // 第一个参数是通过传过来的参数来查找得到的query; 第二个参数是要查询出的行数
        TopDocs hits = searcher.search(query,10);
        // 计算索引结束时间
        long end = System.currentTimeMillis();
        System.out.println("匹配 "+ q + ",查询到 " + hits.totalHits + " 个记录, 用时:" + (end - start));

        // 遍历hits.scoreDocs,得到scoreDoc
        // scoreDoc:得分文档,即得到的文档  scoreDocs:代表topDocs这个文档数组
        for (ScoreDoc scoreDoc : hits.scoreDocs) {
            Document doc = searcher.doc(scoreDoc.doc);
            System.out.println("name:" + doc.get("name") + " ,path=" + doc.get("path"));
        }
        //关闭reader
        reader.close();
    }
}

2、搜索类型

在lucene中,查询就是构建Query对象。搜索文档时会实例化一个IndexSearcher对象,IndexSearcher对象的search()方法完成搜索过程,Query对象作为search()方法的对象。搜索结果会保存在一个TopDoc类型的文档集合中,遍历TopDocs集合输出文档信息。

2.1、多域搜索(MultiFieldQueryParser)

MultiFieldQueryParser可以查询多个字段。示例如下:

String[] fields = {"title","content"};
Analyzer analyzer = new IKAnalyzer6X(true);
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,analyzer);
Query q = parser.parse("日本");

2.2、词项搜索(TermQuery)

TermQuery是最简单也是最常用的Query。在搜索引擎中最基本的搜索就是在索引中搜索某一词条,而TermQuery就是用来完成这项工作的。示例代码:

Term term = new Term("title","美国");
Query q = new TermQuery(term);

2.3、布尔搜索(BooleanQuery)

BooleanQuery是常用的查询,其实际是一个组合查询,在使用时可以把各种Query对象添加进去并标明他们之间的逻辑关系。BooleanQuery本身是一个布尔子句的容积,其专门提供了api方法想其中添加子句,并标明他们之间的关系。代码示例:

Query q1 = new TermQuery(new Term("title","中国"));
Query q2 = new TermQuery(new Term("content","北京"));
BooleanClause bc1 = new BooleanClause(q1, Occur.MUST);
BooleanClause bc2 = new BooleanClause(q2, Occur.MUST_NOT);
BooleanQuery bq = new BooleanQuery.Builder().add(bc1).add(bc2).build();

2.4、范围搜索(RangeQuery )

RangeQuery可以查询满足一定范围的文档,如某段时间的所有文档等。RangeQuery表示在某范围内查询的条件,实现从一个开始词条到一个结束词条的搜索功能。示例如下:

Query rq = IntPoint.newRangeQuery("relay",1000,2000);

2.5、前缀搜索(PrefixQuery)

PrefixQuery就是使用前缀来进行查找的。通常先定义一个词条Term。该词条包含查找的字段名及关键字前缀,然后通过该词条构造一个PrefixQuery对象,就可以进行前缀查询了。示例如下:

Term t = new Term("title","你好");
Query pq = new PrefixQuery(term);

2.6、多关键字搜索(PhraseQuery)

用户搜索时,可能会输入几个不同的关键词,这些关键词要么紧密相连,构成一个精确的短语,要么直接插入其他无关内容。而hraseQuery正可以满足多关键词的查询,其通过add()方法可以向用户添加多个关键字,同时还可通过setSlop()设定坡度变量来确定是否允许或允许多少无关的词汇存在。示例代码:

PhraseQuery.Builder builder = new PhraseQuery.Builder();
builder.add(new Term("title","中国"),2);
builder.add(new Term("title","美国"),3);
PhraseQuery pq = builder.build();

2.7、模糊搜索(FuzzyQuery)

FuzzyQuery是一种模糊搜索,其可以简单识别两个相近的词语。如将“Trump”拼写错误为“tramp”,使用FuzzyQuery可以得到正确的结果。示例如下:

Term t = new Term("title","tramp");
FuzzyQuery fq = new FuzzyQuery(t);

2.8、通配符搜索(WildcardQuery)

WildcardQuery为通配符查询,代码示例:

WildcardQuery wq = new WildcardQuery(new Term("title","学?"));

3、搜索过滤

过滤器是用于缩小搜索空间的一种机制,它把可能的搜索匹配结果仅限制在所有文档的一个子集中。他们可以用来对得到的搜索匹配结果进行进一步的搜索,以实现在搜索结果中继续搜索的特性。此外,它们还可以用来限制文档的搜索空间。安全过滤允许用户只能看到属于自己的文档搜索结果,即时这些查询实际上还是匹配上了其他文档。

TermRangeFilter:只对包含特定项范围的文档进行匹配操作。功能与TermRangeQuery一致,但没有评分操作。TermRangeFilter的处理对象是文本域,如果为数字,需使用NumericRangeFilter。
NumericRangeFilter:复制过滤数值范围的文档。其功能与去除评分功能的NumericRangeQuery类一致;
FieldCacheRangeFilter:提供了另一种范围的过滤选择。它所完成的过滤功能同TermRangeFilter和NumericRangeFilter加起来一样,但它使用的却是基于lucene的域缓存机制。其可以在某些情况下带来系统性能提升。
QueryWrapperFilter:使用查询中匹配的文档来对随后搜索中可以访问的文档进行限制。它允许你将带有评分功能的查询转换为不带评分功能的过滤器。使用QueryWrapperFilter可以将被搜索文档限制在特定的类别范围内。
SpanQueryFilter:SpanQueryFilter完成与QueryWrapperFilter一样的功能,区别是前者能够保留针对每个匹配文档的跨度。
PerfixFilter:其是PrefixQuery的必然结果,它会对包含以特定前缀开始的项的文档进行匹配。我们可以用PrefixFilter来讲搜索范围限制在某个指定类别的所有书籍中。

你可能感兴趣的:(搜索引擎Lucene(5):搜索执行过程及搜索类型)