lucene--7.索引维护之查询

本文介绍Lucene查询的基础知识,包括创建查询对象的方法、使用不同类型的查询实现特定需求,如条件查询、组合查询等,并展示了如何利用QueryParser进行复杂查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1      概述

1.1    查询对象

         对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。

         可通过两种方法创建查询对象:

         1)使用Lucene提供Query子类

         Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。

         如下代码:

    Query query = new TermQuery(new Term("name", "lucene"));

 

         2)使用QueryParse解析查询表达式

         QueryParse会将用户输入的查询表达式解析成Query对象实例。

         如下代码:

         QueryParser queryParser = new QueryParser("name", new IKAnalyzer());

       Query query =queryParser.parse("name:lucene");

 

1.2    公共类抽取

//IndexReader  IndexSearcher
public IndexSearcher getIndexSearcher() throws Exception{
   // 第一步:创建一个Directory对象,也就是索引库存放的位置。
   Directory directory = FSDirectory.open(new File("F:\\lucene\\index"));// 磁盘
   // 第二步:创建一个indexReader对象,需要指定Directory对象。
   IndexReader indexReader = DirectoryReader.open(directory);
   // 第三步:创建一个indexsearcher对象,需要指定IndexReader对象
   return new IndexSearcher(indexReader);
}
//执行查询的结果
public void printResult(IndexSearcher indexSearcher,Queryquery)throws Exception{
   // 第五步:执行查询。
   TopDocs topDocs = indexSearcher.search(query, 10);
   // 第六步:返回查询结果。遍历查询结果并输出。
   ScoreDoc[] scoreDocs = topDocs.scoreDocs;
   for (ScoreDocscoreDoc : scoreDocs) {
      int doc = scoreDoc.doc;
      Document document =indexSearcher.doc(doc);
      // 文件名称
      String fileName = document.get("fileName");
      System.out.println(fileName);
      // 文件内容
      String fileContent = document.get("fileContent");
      System.out.println(fileContent);
      // 文件大小
      String fileSize = document.get("fileSize");
      System.out.println(fileSize);
      // 文件路径
      String filePath = document.get("filePath");
      System.out.println(filePath);
      System.out.println("------------");
   }
}

2      Api使用(二选一)

2.1    使用query的子类查询

2.1.1  MatchAllDocsQuery(查询所有)

使用MatchAllDocsQuery查询索引目录中的所有文档

//查询所有
@Test
public void testMatchAllDocsQuery() throws Exception{
   IndexSearcher indexSearcher =getIndexSearcher();
   Query query = new MatchAllDocsQuery();
   System.out.println(query);
   printResult(indexSearcher, query);
   //关闭资源
   indexSearcher.getIndexReader().close();
}

2.1.2  TermQuery(条件查询/项查询)

TermQuery,通过项查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。

指定要查询的域和要查询的关键词。

//使用Termquery查询
	@Test
	public void testTermQuery() throws Exception {
		IndexSearcher indexSearcher = getIndexSearcher();
		//创建查询对象
		Query query = new TermQuery(new Term("content", "lucene"));
		//执行查询
		TopDocs topDocs = indexSearcher.search(query, 10);
		//共查询到的document个数
		System.out.println("查询结果总数量:" + topDocs.totalHits);
		//遍历查询结果
		for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
			Document document = indexSearcher.doc(scoreDoc.doc);
			System.out.println(document.get("filename"));
			//System.out.println(document.get("content"));
			System.out.println(document.get("path"));
			System.out.println(document.get("size"));
		}
		//关闭indexreader
		indexSearcher.getIndexReader().close();
	} 

2.1.3         NumericRangeQuery(根据数值范围查询)

可以根据数值范围查询。//参数:1.域名 2.最小值 3.最大值 4.是否包含最小值 5.是否包含最大值

 

//根据数值范围查询
@Test
public void testNumericRangeQuery() throws Exception{
   IndexSearcher indexSearcher =getIndexSearcher();
   
   Query query = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, false, true);
   System.out.println(query);
   printResult(indexSearcher, query);
   //关闭资源
   indexSearcher.getIndexReader().close();
} 

2.1.4  BooleanQuery(组合查询)

可以组合查询条件。

//可以组合查询条件
@Test
public void testBooleanQuery() throws Exception{
   IndexSearcher indexSearcher =getIndexSearcher();
   //创建一个布尔查询对象
   BooleanQuery booleanQuery = new BooleanQuery();
   //创建第一个查询条件
   Query query1 = new TermQuery(new Term("fileName","apache"));
   Query query2 = new TermQuery(newTerm("fileName","lucene"));
   //  select * fromuser where id =1 or name = 'safdsa'
   //组合查询条件
   booleanQuery.add(query1, Occur.MUST);
   booleanQuery.add(query2, Occur.SHOULD);
   System.out.println(booleanQuery);
   printResult(indexSearcher,booleanQuery);//执行查询
   //关闭资源
   indexSearcher.getIndexReader().close();
}

Occur.MUST:必须满足此条件,相当于and

Occur.SHOULD:应该满足,但是不满足也可以,相当于or

Occur.MUST_NOT:必须不满足。相当于not 

2.2    使用queryparser查询

2.2.1  概念

通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。

需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。

需要加入queryParser依赖的jar包。


2.2.2  程序实现

//条件解释的对象查询
@Test
public void testQueryParser() throws Exception{
   IndexSearcher indexSearcher =getIndexSearcher();
   //创建queryparser对象
   //参数1: 默认查询的域  
   //参数2:采用的分析器
   QueryParser queryParser = new QueryParser("fileName",newIKAnalyzer());
   // *:*   域:值
   Query query = queryParser.parse("fileName:lucene is apache ORfileContent:lucene is apache");
   
   printResult(indexSearcher, query);
   //关闭资源
   indexSearcher.getIndexReader().close();
} 

2.2.3  查询语法

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

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

例如:content:java

2、范围查询

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

例如:size:[1 TO 1000]

范围查询在lucene中支持数值类型,不支持字符串类型。在solr中支持字符串类型。

3、组合条件查询

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

例如:+filename:apache+content:apache

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

例如:+filename:apache content:apache

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

例如:filename:apachecontent:apache

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

例如:-filename:apachecontent:apache

 

第二种写法:

条件1 AND 条件2

条件1 OR 条件2

条件1 NOT 条件2

 

2.2.4  MultiFieldQueryParser

可以指定多个默认搜索域

//条件解析的对象查询   多个默念域
@Test
public void testMultiFieldQueryParser() throws Exception{
   IndexSearcher indexSearcher =getIndexSearcher();
   
   String[] fields = {"fileName","fileContent"};
   //参数1:默认查询的域  
   //参数2:采用的分析器
   MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields,new IKAnalyzer());
   // *:*   域:值
   Query query = queryParser.parse("lucene is apache");
   
   printResult(indexSearcher, query);
   //关闭资源
   indexSearcher.getIndexReader().close();
} 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值