开发者学堂课程【Lucene知识精讲与实战(下):高级查询(文本查询)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/701/detail/12344
高级查询(文本查询)
内容介绍:
一、高级搜索
二、文本搜索
一、高级搜索
下面进行高级搜索的讲解,和之前提及的根据 QueryParser 根据某一个域的搜索,QueryParser 也是在 Lucene 中建议使用的一个对象,也就是根据文本查询的对象,高级搜索分为三个内容:根据文本搜索、根据数值范围搜索(比如说需要购买一件东西,买东西是有预算的,这个预算往往是在一个数值范围内的,这就是根据数值范围搜索)和组合搜索(如果想买一个东西,即需要根据价格范围进行查询,还要输入关键字比如手机,这样组合的搜索查询出来的结果就是组合搜索),接下来讲解的是文本搜索。
二、文本搜索
高级的文本搜索是这样的。
1.请看以下部分代码:
@Test
public void testIndexSearch()throws Exception
{
1.创建分词器(对搜素的关键调进行分词使用)
//注意:分词器要和创建素引的时候使用的分词器一模一样
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;
之前在搜索关键字时候,输入手机就可以进行手机的查询,如果输入华为手机,就需要看使用分词器的类型。
(1)假设使用的是标准分词器,那么对中文就是单字分词,也就是把华为手机分成四个词,此时关键字就是:华 为 手 机。使用这四个字,然后去索引库搜索,分别会通过:华 为 手 机 四个词搜出四个结果,这四个结果里面的数据可能有重复,也有可能不重复;最终返回的结果要有一个结果,所以需要对四个结果进行处理,这里是求交集或者求并集。
如图:
对华为手机进行查询,可以看到,结果是24147条。
(2)如果把华为手机进行空格加上 AND ,也就是变成华为 AND 手机,AND 是并且的意思,也就是求交集,这时候再对其查询,。
如图:
可以看到,结果变成7668条,这个范围明显比之前的小,所以说明求的是交集。
(3)如果把华为 AND 手机改为华为 OR手机,就是求并集的意思。
如图:
对其进行查询,结果是24147。可以看到,对华为手机和华为 OR 手机进行查询都是在求并集,只有华为AND 手机才是求交集。
这里面是有语法,语法就是关键字或者关键词之间用空格隔开,中间加大写字母AND 是求交集,加 OR 是求并集;如果不添加大写字母,也就是华为手机,按照分词器的分词规则,对输入的关键字进行切分词,分出来的词会分别在索引库进行搜索,搜索出的一系列结果中默认是求并集。对于重复的组合还会进行去重。
以上就是关于文本的高级搜索。
2.根据价格进行范围查询
如果想根据价格进行范围查询,看创建索引库,价格域是 prize。
修改上面的代码,将其变为:
1.创建分词器(对搜素的关键调进行分词使用)
//注意:分词器要和创建素引的时候使用的分词器一模一样
Analyzer analyzer = new StandardAnalyzer();
//2.创建查询对象,
//第一个参数:认查询城,如果查询的关键字中带搜索的域名,则以指定域中查询,如果不带域名则从,默认搜索域中查询
//第二个参数:使用的分词器
QueryParser queryParser = new QueryParser("name",analyzer);
//3、设置搜素关键词
Query query = queryParser.parse("prize")
;
//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;
输入要搜索的域名 prize,价格是一个数值,有范围差别。由于 QueryParser 不支持默认搜索域,默认搜索域指不输入域名,此时从 name 域搜索,如果输入了域名 prize 就从这个域搜索。这也很容易看出查询语法的格式。根据价格搜索,这里的语法是:域名:[1 TO 99999],里面填最小值比如1,加上 TO 和最大值比如99999,查询这个范围内。
如图:
没有显示任何内容,原因是 QueryParser 只能对文本进行搜索,不能对数值范围的域进行搜索,如果要对数值范围的域进行搜索,请听下节课的讲解。