自己动手写分布式搜索引擎
上QQ阅读APP看书,第一时间看更新

3.3.2 常用查询

Query是一个用于查询的抽象基类,有各种具体查询实现类,比如实现基本词查询的TermQuery、实现布尔逻辑查询的BooleanQuery、实现短语查询的PhraseQuery、实现前缀匹配查询的PrefixQuery、实现区间查询的RangeQuery、实现多词查询的MultiTermQuery、实现过滤条件查询的FilteredQuery、约束多个查询词密集度的SpanQuery等。

对于复杂查询,需要调用rewrite()方法使其变成简单的查询。例如,一个PrefixQuery将被重写成由TermQuery组成的BooleanQuery。

可以使用QueryParser查询分词列。一般不需要查询没有使用分词的列,如果要查询,可以使用TermQuery查询,例如url列。

最基本的词条查询使用TermQuery,用来查询不切分的字段。例如查询一个杂志:

        Term term = new Term("journal_id", "1672-6251");
        TermQuery query = new TermQuery(term);

为了方便测试查询,使用createDocument()方法索引测试内容。

        private static Document createDocument(String id, String content) { //创建文档
            Document doc = new Document();
            doc.add(new Field("id", id, StringField.TYPE_STORED)); //索引不分词的字符串列
            //索引分词的文本列
            doc.add(new Field("contents", content, TextField.TYPE_STORED));
            return doc;
        }

组合条件查询使用布尔逻辑查询BooleanQuery。下面举一个布尔逻辑查询的例子:同时查询标题列和内容列。使用BooleanClause.Occur.SHOULD的查询效果如图3-10所示。

图3-10 BooleanClause.Occur.SHOULD查询效果

        QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "body",
        analyzer);
        Query bodyQuery =  parser.parse("NBA"); //查询内容列
        parser = new QueryParser(Version.LUCENE_CURRENT, "title", analyzer);
        Query titleQuery = parser.parse("NBA"); //查询标题列


        BooleanQuery bodyOrTitleQuery = new BooleanQuery();
        //用OR条件合并两个查询
        bodyOrTitleQuery.add(bodyQuery, BooleanClause.Occur.SHOULD);
        bodyOrTitleQuery.add(titleQuery, BooleanClause.Occur.SHOULD);


        //返回前10条结果
        ScoreDoc[] hits = isearcher.search(bodyOrTitleQuery, 10).scoreDocs;