开发者学堂课程【Lucene知识精讲与实战(下):高级查询(数组查询和组合查询)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:httpshttps://developer.aliyun.com/learning/course/701/detail/12345
高级查询(数组查询和组合查询)
内容介绍:
一、数值范围的查询
二、组合查询
一、数值范围的查询
接下来进行数值范围的查询,也就是根据某一个数值的域,通过它的最小值和最大值范围的区间段来进行查询。
举例:比如说买东西,根据价格来进行查询,这个价格有最小值也有最大值,在这个范围内进行价格的查询。
1.数值范围查询的演示
(1)需求描述:查询价格大于100,小于等于1000的商品。价格的数值可自拟。
(2)修改代码
由于很多代码是重复的,所以可以直接把文本域的查询的代码复制粘贴,在原有的基础上修改部分代码,再进行演示。
请看以下代码:
@Test
public void testIndexSearch()throws Exception
{
2.创建分词器(对搜素的关键调进行分词使用)
//注意:分词器要和创建素引的时候使用的分词器一模一样
Analyzer analyzer = new StandardAnalyzer();
//2.创建查询对象,
//第一个参数:认查询城,如果查询的关键字中带搜索的域名,则以指定域中查询,如果不带域名则从,默认搜索域中查询
//第二个参数:使用的分词器
QueryParser queryParser = new QueryParser("name",analyzer);
//3、设置搜素关键词
Query query = queryParser.parse("
手机");
//4。创建Directory目录对象,指定素引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5,创建输入流对象
IndexReader indexReader= DirectoryReader.open(dir);
//6.创建搜素对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//7.搜索,并返回结果
//第二个参数:是返回多少条数据用于展示,分页使用
TopDocs topDocs = indexSearcher.search(query,10);
//获取查询到的结果集的总数,打印
Systen.out.println("=======count======="+topDocs.totalHits);
//8,获取结果集
ScoreDoc[scoreDocs = topDocs.scoreDocs;
进行部分代码的修改:
①把第一行的 testIndexSearch 改为 testRangeQuery,其中 Range 是范围查询的意思。
②把文本域对象改为根据范围查询也就是价格 prize 域。
如图:
价格查询在创建域的时候就是 IntPoint 格式,也就是 Int 类型。
这里还需要删除原来的部分代码:
//第一个参数:认查询城,如果查询的关键字中带搜索的域名,则以指定域中查询,如果不带域名则从,默认搜索域中查询
//第二个参数:使用的分词器
QueryParser queryParser = new QueryParser("name",analyzer);
//3、设置搜素关键词
Query query = queryParser.parse("
手机");
然后添上:
Query query = IntPoint.newRangeQuery(“prize”,100,99999);
其中,LowerValue 是最小值,upValue 是最大值。域名是 prize,最小值是100,这里把最大值改为99999。
(3)请看以下修改后的代码:
/**
/*数值范围查询
*@throws Exception
/*
@Test
public void testRangeQuery()throws Exception
{
1.创建分词器(对搜素的关键调进行分词使用)
//注意:分词器要和创建素引的时候使用的分词器一模一样
Analyzer analyzer = new StandardAnalyzer();
//2.创建查询对象,
Query query = IntPoint.newRangeQuery(“prize”,100,99999);
//4。创建Directory目录对象,指定素引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5,创建输入流对象
IndexReader indexReader= DirectoryReader.open(dir);
//6.创建搜素对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//7.搜索,并返回结果
//第二个参数:是返回多少条数据用于展示,分页使用
TopDocs topDocs = indexSearcher.search(query,10);
//获取查询到的结果集的总数,打印
Systen.out.println("=======count======="+topDocs.totalHits);
//8,获取结果集
ScoreDoc[scoreDocs = topDocs.scoreDocs;
(4)执行代码
如图:
这里有936916条结果。
假设查询的范围是100到1000,如图:
执行代码,如图:
这里有8641条结果。
以上就是根据数值范围的查询。
二、组合查询
组合查询就是把多个查询条件组合在一起的查询。
举例需求是既希望能用华为手机作为关键字进行查询,又希望它的价格范围在100到1000内的查询
1.演示
(1)把上面的代码进行复制粘贴,在此基础上进行代码的修改。
①修改查询对象
②把 testRangeQuery 改为 testBoolearQuery,Boolear 是组合查询的意思
③在之前添加的代码后面,加上根据关键字查询的查询条件的代码:
QueryParser queryParser = new QueryParser("name",analyzer);
//3、设置搜素关键词
//华 OR 为 手 机
Query query = queryParser.parse("
华为手机");
//创建布尔查询对象(组合查询对象)
/**
* BooleanClause.Occur.MUST 必须相当于 and,也就是并且的关系。两个条件都满足。
* BooleanClause.Occur.SHOULD 应该相当于 OR,也就是或者的关系。两个条件满足一个即可。
* BooleanClause.Occur.MUST_NOT 不必须,相当于 not,非。
*注意:如果查询条件都是 MUST_NOT,或者只有一个查询条件,然后这个查询条件是MUST_NOT,则查询不出任何数据
*/
BooleanQuery.Builder builder = new BooleanQuery.Builder();
query.add(query1, BooleanClause.Occur.MUST_NOT);
query.add(query2, BooleanClause.Occur.MUST);
打开 Builder,如图:
可以看到,它是 Boolean 查询这个类内部的一个构建器,通过构建器进行 Boolean 查询
(2)请看以下修改后的代码:
/**
*组合查询
*@throws Exception
*/
@Test
public void testBooleanQuery()throws Exception
{
1.创建分词器(对搜素的关键调进行分词使用)
//注意:分词器要和创建素引的时候使用的分词器一模一样
Analyzer analyzer = new StandardAnalyzer();
//2.创建查询对象,
Query query 1= IntPoint.newRangeQuery(“prize”,100,1000);
QueryParser queryParser = new QueryParser("name",analyzer);
//3、设置搜素关键词
//华 OR 为 手 机
Query query2 = queryParser.parse("
华为手机");
//创建布尔查询对象(组合查询对象)
/**
* BooleanClause.Occur.MUST 必须相当于 and,也就是并且的关系。两个条件都满足。
* BooleanClause.Occur.SHOULD 应该相当于 OR,也就是或者的关系。两个条件满足一个即可。
* BooleanClause.Occur.MUST_NOT 不必须,相当于 not,非。
*注意:如果查询条件都是 MUST_NOT,或者只有一个查询条件,然后这个查询条件是MUST_NOT,则查询不出任何数据
*/
BooleanQuery.Builder builder = new BooleanQuery.Builder();
query.add(query1, BooleanClause.Occur.MUST_NOT);
query.add(query2, BooleanClause.Occur.MUST);
//4。创建Directory目录对象,指定素引库的位置
Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
//5,创建输入流对象
IndexReader indexReader= DirectoryReader.open(dir);
//6.创建搜素对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//7.搜索,并返回结果
//第二个参数:是返回多少条数据用于展示,分页使用
TopDocs topDocs = indexSearcher.search(query,10);
//获取查询到的结果集的总数,打印
Systen.out.println("=======count======="+topDocs.totalHits);
//8,获取结果集
ScoreDoc[scoreDocs = topDocs.scoreDocs;
如果两个查询条件是并且的关系,就是指查询条件中既包括华为手机,并且包括价格在100到1000范围内
如果两个查询条件是或者的关系,就是指查询条件中满足华为手机或者价格在100到1000范围内,两个条件只需要满足一个。
(3)执行代码,如图:
可以看到,这里的查询对象出了问题。
把TopDocs topDocs = indexSearcher.search(query,10);
中的 query 改为query.builder()
重新执行,如图:
这里有23904条结果。
(4)如果把第二个条件也改为 NOT,此时查询关键字,不包含华为手机,也不包含价格范围。
如图:
结果为0。原因是对服务器的管控,用户在使用百度等搜索引擎时只需要输入Lucene 就可以查询到有关 Lucene 的数据,但是用户不能查找到和 Lucene 无关的数据。所以,如果查询条件都是 MUST_NOT,或者只有一个查询条件,然后这个查询条件是 MUST_NOT,则查询不出任何数据。
(5)这里用户明显是希望查找华为手机并且价格在100到1000范围内的数据。
如图:
两个条件是并且的关系。
执行代码,如图:
满足华为手机,并且价格在100到1000范围内两个条件的结果有243条。
以上就是组合查询的演示。至此,高级查询的讲解完毕。