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

3.6 查询语法与解析

Lucene不仅提供了API来自己创建查询,而且还通过查询分析器提供了丰富的查询语言。

● 一个短语查询可以用双引号括起来,这样只有精确匹配该短语的文档才会匹配查询条件。比如,搜索“上海世博会”只会出现包含连续出现“上海”和“世博会”的文档。如果“上海”和“世博会”之间有其他词,则不会匹配这样的情况。所以搜索“上海世博会”“上海AND世博会”这样的查询返回的结果更少。

● 使用^表示加权。例如搜索“solr^4 lucene”

● 修饰符“+”“-”“NOT”。例如搜索“+solr lucene”

● 布尔操作符“OR”“AND”。例如搜索“(solr OR lucene) AND user”。注意这里的AND必须是大写的,如果是小写,即and,就会被当作普通查询词看待了。

● 按域查询。一个字段名后面跟冒号,再加上要搜索的词语或短句,就可以把搜索条件限制在该字段。例如搜索“title:NBA”,匹配标题包含NBA的文档。

QueryParser将输入查询字串解析为Lucene的Query对象,如图3-17所示。

图3-17 使用查询表达式搜索

下面两个写法在功能上是等价的:

    QueryParser parser = new QueryParser("name", wrapper);
    Query query = parser.parse("size:small AND color:blue");

    BooleanQuery skuQuery = new BooleanQuery();
    skuQuery.add(new TermQuery(new Term("size", "small")), Occur.MUST);
    skuQuery.add(new TermQuery(new Term("color", "blue")), Occur.MUST);

可以检查返回的结果:

    QueryParser parser = new QueryParser("title",
                    analyzer);
    Query query = parser.parse("Monitor");
    System.out.println(query.getClass().getName());
    //org.apache.lucene.search.TermQuery

这表示QueryParser.parse()方法返回的是一个简单的TermQuery。

直接这样写可能找不到结果:

    Query query = new QueryParser("url", analyzer).parse(url);

需要把URL地址中的特殊字符当作普通字符看待。

        Query query = new QueryParser("url",
                                  analyzer).newTermQuery(
                                            new Term("url", url)).parse(url);

有一些特殊字符,如单引号、转义符等符号,怎么让Lucene忽略它们,而把它们当作一般的字符串去查询?方法是使用“\\”转义或者直接调用org.apache.lucene.queryparser. classic.QueryParserBase.escape(String)方法。