前言

本文我们来对Lucene具体如何进行数据的搜索,进行详细的介绍。

环境准备

我们直接使用在 Lucene应用实战(二)——Field域的使用及索引库的维护 中的应用代码案例。

因为索引和存储两者是分开的,对于某一个字段我们可以建立索引,但是不存储,我们依然可以对此字段进行搜索,但是因为我们没有存储,所以我们搜索出来的结果中不显示此字段的内容。

本文为了结果的展示明显,我们将“desc“属性进行索引并且存储。

搜索结果TopDocs类

Lucene搜索结果可通过TopDocs遍历,TopDocs类提供了少量的属性,如下:

方法或属性说明
totalHits匹配搜索条件的总记录数
scoreDocs顶部匹配记录

注意: Search方法需要指定匹配记录数量n:search(query, n)

TopDocs.totalHits:是匹配索引库中所有记录的数量;

TopDocs.scoreDocs:匹配相关度高的前边记录数组,scoreDocs的长度小于等于search方法指定的参数n

方式一 使用Lucene提供的Query子类

公共测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  void  doSearch(Query query)throws  Exception{
// 创建Directory 流对象
Directory directory = FSDirectory.open(Paths.get("D:/lucene/index"));
// 创建IndexReader
IndexReader indexReader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(indexReader);
// 获取TopDocs
TopDocs topDocs = searcher.search(query,10);
System.out.println("查询索引总条数:" + topDocs.totalHits);
ScoreDoc[] docs = topDocs.scoreDocs;
// 解析结果集
for (ScoreDoc scoreDoc : docs){
int docID = scoreDoc.doc;
Document document = searcher.doc(docID);

System.out.println("docID:"+docID);
System.out.println("bookId:"+document.get("id"));
System.out.println("name:"+document.get("name"));
System.out.println("price:"+document.get("price"));
System.out.println("desc:"+document.get("desc"));
}
indexReader.close();
}

TermQuery

简介

TermQuery词项查询,TermQuery不使用分词器,搜索关键词进行精确匹配Field域中的词,比如订单 号、分类ID号等。

测试

1
2
3
4
5
6
7
 @Test
public void testSearchTermQuery()throws Exception{
// 创建TermQuery 搜索对象
Query query = new TermQuery(new Term("name","lucene"));

doSearch(query);
}

结果

1
2
3
4
5
6
查询索引总条数:1
docID:0
bookId:1
name:Lucene
price:100.45
desc:Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core.

BooleanQuery

简介

BooleanQuery,布尔查询,实现组合条件查询。

组合关系代表的意思如下:

1、MUST和MUST表示“与”的关系,即“交集”;

2、MUST和MUST_NOT前者包含后者不包含;

3、MUST_NOT和MUST_NOT没意义;

4、SHOULD与MUST表示MUST,SHOULD失去意义;

5、SHOULD与MUST_NOT相当于MUST与MUST_NOT;

6、SHOULD与SHOULD表示“或”的关系,即“并集”。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 @Test
public void testSearchBooleanQuery() throws Exception {
// 创建两个 TermQuery搜索对象
Query query1 = new TermQuery(new Term("name", "lucene"));
Query query2 = new TermQuery(new Term("desc", "java"));
// 创建BooleanQuery搜索对象,组合查询条件
BooleanQuery.Builder boolQuery = new BooleanQuery.Builder();
// 组合条件,
// 第一个参数,查询条件,第二个参数,组合方式
boolQuery.add(query1, BooleanClause.Occur.MUST);
boolQuery.add(query2, BooleanClause.Occur.MUST);

doSearch(boolQuery.build());
}

结果

1
2
3
4
5
6
查询索引总条数:1
docID:0
bookId:1
name:Lucene
price:100.45
desc:Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core.

PhraseQuery

phraseQuery即短语查询,代码实例:

1
2
3
4
5
6
7
 @Test
public void testSearchPhraseQuery()throws Exception{
PhraseQuery query = new PhraseQuery("name","lucene");
//跨三个词查询,比如这个是查lucene和Java中间跨了三个词之内的内容
// PhraseQuery query = new PhraseQuery(3,"desc","lucene","java");
doSearch(query);
}

结果:

1
2
3
4
5
6
查询索引总条数:1
docID:0
bookId:1
name:Lucene
price:100.45
desc:Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core.

PhraseQuery query = new PhraseQuery(3,"desc","lucene","java");这个短语查询会匹配到Lucene Core is a Java。因为Lucene和Java中间间隔的单词是3个以内的。

跨度查询

跨度查询,如下所示查询的结果是“lucene”和“Java“两个词中间跨度为3以内的句子:

1
2
3
4
5
6
7
   @Test
public void testSearchSpanNearQuery()throws Exception{
SpanTermQuery tq1 = new SpanTermQuery(new Term("desc", "lucene"));
SpanTermQuery tq2 = new SpanTermQuery(new Term("desc", "java"));
SpanNearQuery spanNearQuery = new SpanNearQuery(new SpanQuery[] { tq1, tq2 },3,true);
doSearch(spanNearQuery);
}

结果:

1
2
3
4
5
6
查询索引总条数:1
docID:0
bookId:1
name:Lucene
price:100.45
desc:Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core.

模糊查询

WildcardQuery:通配符查询, *表示0个或多个字符,?表示1个字符,\是转义符。通配符查询可能会比较慢,不可以通配符开头(那样就是所有词项了)

示例:

1
2
3
4
5
6
7
   @Test
public void testSearchLikeQuery()throws Exception{
WildcardQuery wildcardQuery = new WildcardQuery( new Term("name", "so??"));
doSearch(wildcardQuery);
// FuzzyQuery fuzzyQuery = new FuzzyQuery(new Term("name", "slorss"), 2);
// doSearch(fuzzyQuery);
}

结果:

1
2
3
4
5
6
查询索引总条数:1
docID:1
bookId:11
name:Solr
price:320.45
desc:Solr is highly scalable, providing fully fault tolerant distributed indexing, search and analytics. It exposes Lucene's features through easy to use JSON/HTTP interfaces or native clients for Java and other languages.

数值查询

通过 IntPoint, LongPoint, FloatPoint, DoublePoint 中的方法构建对应的查询。

示例:

1
Query pointRangeQuery = IntPoint.newRangeQuery("id", 1,11);

方式二 使用QueryParser进行搜索

查询语法

  1. 基础的查询语法,关键词查询:

    域名+“:”+搜索的关键字

    例如:name:java

  2. 范围查询

    域名+“:”+[最小值 TO 最大值]

    例如:size:[1 TO 1000]

    注意:QueryParser不支持对数字范围的搜索,它支持字符串范围。数字范围搜索建议使用对应的 Point。

  3. 组合条件查询

第一种写法

1)+条件1 + 条件2:两个条件之间是并且的关系and

例如:+filename:lucene + content:lucene

2)+条件1 条件2:必须满足第一个条件,应该满足第二个条件

例如:+filename:lucene content:lucene

3)条件1 条件2:两个条件满足其一即可。

例如:filename:lucene content:lucene

4)-条件1条件2:必须不满足条件1,要满足条件2

例如:-filename:lucene content:lucene

逻辑实现
Occur.MUST 查询条件必须满足,相当于AND+(加号)
Occur.SHOULD 查询条件可选,相当于OR空(不用符号)
Occur.MUST_NOT 查询条件不能满足,相当于NOT非-(减号)

第二种写法

  条件1 AND 条件2

  条件1 OR 条件2

  条件1 NOT 条件2

代码示例

1
2
3
4
5
6
7
8
 @Test
public void testQueryPasrser() throws Exception{
Analyzer analyzer = new StandardAnalyzer();
QueryParser queryParser = new QueryParser("desc",analyzer);
// 构建搜索对象
Query query = queryParser.parse("desc:java AND name:lucene");
doSearch(query);
}

执行结果:

1
2
3
4
5
6
查询索引总条数:1
docID:0
bookId:1
name:Lucene
price:100.45
desc:Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core.

源码

lucene索引实战demo

总结

本文主要对Lucene如何进行搜索做了详细的介绍,主要有使用Query子类和QueryParser进行搜索两种方式。