Lucene的查询、Occur.SHOULD Occur.MUST Occur.MUST_NOT的组合使用
程序员文章站
2022-07-09 09:35:12
...
- 1.MUST和MUST:取得连个查询子句的交集。
- 2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。
- 3.SHOULD与MUST_NOT:连用时,功能同MUST和MUST_NOT。
- 4.SHOULD与MUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。
- 5.SHOULD与SHOULD:表示“或”关系,最终检索结果为所有检索子句的并集。
- 6.MUST_NOT和MUST_NOT:无意义,检索无结果。
查看本文章 前,可参考前一篇文章,因为它是在上一篇的基础进行测试的,基本测试代码如下:
package com.ckinghan.lucene;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiDocsAndPositionsEnum.EnumWithSlice;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
public class QuerIndex {
/**
* 查询lucene索引数据 @创建时间:2017年10月7日22:57:00
*/
public void query(Query query) {
try {
// 指定查询的索引目录
Directory directory = FSDirectory.open(new File("D:" + File.separator + "lucene_index" + File.separator));
// 创建流对象
IndexReader reader = DirectoryReader.open(directory);
// 通过流对象创建索引搜索对象
IndexSearcher searcher = new IndexSearcher(reader);
// 将查询到的指定索引域数据赋值给TopDocs
TopDocs topDocs = searcher.search(query, 10);
// 根据获取查询到的总数据
int totalHits = topDocs.totalHits;
// 输出
System.out.println("共查询到数据总数为:" + totalHits);
System.out.println();
// 将查询到的索引数据赋值给数组
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
// 如果未查询到数据,则输出提示
if (scoreDocs == null || scoreDocs.length == 0) {
System.out.println("未查询到数据");
} else {
// 如果查询到的有数据。则循环输出
for (ScoreDoc doc : scoreDocs) {
// 获取索引ID
int docID = doc.doc;
// 根据索引数据查询文档中对应的数据
Document document = searcher.doc(docID);
// 将查询到的数据输出
System.out.println("ID:" + document.get("id"));
System.out.println("name:" + document.get("name"));
System.out.println("price:" + document.get("price"));
System.out.println("pic:" + document.get("pic"));
System.out.println("description:" + document.get("description"));
System.out.println("==================================");
System.out.println();
System.out.println();
}
}
// 关闭流
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建第一种查询方法–》QueryParse查询,这个查询方法用的比较多。
/**
* QueryParse查询 @创建时间:2017年10月7日23:00:15
*/
@Test
public void queryParser() throws ParseException {
// 创建分词对象
Analyzer analyzer = new StandardAnalyzer();
// 通过指定的分词对象、查询域名称创建QueryParser
QueryParser parser = new QueryParser("id", analyzer);
// 指定查询条件创建query
Query query = parser.parse("id:7");
// 查询
query(query);
}
因为ID为7的数据是在测试更新的方法创建的,并未将所有数据补充完整,所有会有一部分数据为空。执行结果如下:
共查询到数据总数为:1
ID:7
name:null
price:null
pic:null
description:null
==================================
创建第二种查询方法–》TermQuery查询,代码如下:
@Test
public void termQuery() {
//Term是lucene最小的查询单位了,一般会指定查询的域名及查询的值
Query query = new TermQuery(new Term("name", "java"));
// 调用方法查询
query(query);
}
查询结果如下:
共查询到数据总数为:1
ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================
创建第三种查询方法–》NumericRangeQuery查询 ,它有很多重载的方法,根据须要选择,代码如下,
/**
* NumericRangeQuery查询 @创建时间:2017年10月7日23:09:55
*/
@Test
public void numbericRangeQuery() {
// NumbericRangeQuery 参数:查询域名称,最小值,最大值 ,是否包含最小值,是否包含最大值
Query query = NumericRangeQuery.newFloatRange("price", 10f, 60f, true, true);
// 查询
query(query);
}
查询price的值10f/60f之间的结果如下:
共查询到数据总数为:2
ID:4
name:天气你好啊哦咯看i我看
price:22.22
pic:365456564.jpg
description:null
==================================
ID:5
name:爱奇艺
price:54.25
pic:adsfasdfa.jpg
description:null
==================================
创建第四种查询方法–》BooleanQuery查询,这个玩意就比较复杂了,代码如下:
/**
* BooleanQuery查询
* @创建时间:2017年10月7日23:19:07
* Occur参数说明:
* Occur.MUST : 必须满足查询条件
* Occur.MUST_NOT : 不满足条件的数据
* Occur.SHOULD : 逻辑OR
*
* 组合功能如下:
* 1.MUST和MUST:取得连个查询子句的交集。
* 2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。
* 3.SHOULD与MUST_NOT:连用时,功能同MUST和MUST_NOT。
* 4.SHOULD与MUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。
* 5.SHOULD与SHOULD:表示“或”关系,最终检索结果为所有检索子句的并集。
* 6.MUST_NOT和MUST_NOT:无意义,检索无结果。
*/
@Test
public void booleanQuery() {
BooleanQuery query = new BooleanQuery();
Query termQuery = new TermQuery(new Term("name", "java"));
Query numericRangeQuery = NumericRangeQuery.newFloatRange("price", 10f, 60f, true, true);
query.add(termQuery, Occur.SHOULD);
query.add(numericRangeQuery, Occur.SHOULD);
// 查询
query(query);
}
查询的结果如下:
共查询到数据总数为:3
ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================
ID:4
name:天气你好啊哦咯看i我看
price:22.22
pic:365456564.jpg
description:null
==================================
ID:5
name:爱奇艺
price:54.25
pic:adsfasdfa.jpg
description:null
==================================
创建第五种查询方式–》multiFieldQueryParser(),这个功能很强大,具体代码如下:
/**
* 条件组合查询:
* Occur.MUST 必须满足 相当于and 可以用+代表
* Occur.MUST_NOT 不满足 相当于not 可以用-代表
* Occur.SHOULD 或操作 相当于or 可以用空代表
* 例如:
* +name:java +description:spring 代码必须同时满足这两个条件,相当于and的
* +name:java description:spring 必须满足name=java,后面的条件忽略
* name:java description:spring 满足任义一个就可以,相当于or
* +name:java -description:spring 必须满足name=java and description<>spring
*
* 范围查询:
* price:[10f TO 100f] 相当于SQL语句中的 price between 10f and 100f
* 注意:QueryParser不支持对数字范围的搜索,它支持字符串范围。数字范围搜索建议使用NumericRangeQuery。
*
*
* @创建时间:
*/
@Test
public void multiFieldQueryParser() throws ParseException{
//指定多个查询域名称
String[] fields = {"name","description"};
//指定分词对象
Analyzer analyzer = new StandardAnalyzer();
//创建多域名查询对象
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(fields, analyzer);
//以下三种方法相等,查询name = java or description = java的对象
//Query query = multiFieldQueryParser.parse("name:java description:java");
//Query query = multiFieldQueryParser.parse("name:java OR description:java");
Query query = multiFieldQueryParser.parse("java");
//输出query的查询语句内容
System.out.println(query);
//查询
query(query);
}
执行结果如下 :
name:java description:java
共查询到数据总数为:1
ID:3
name:java spring mybatis Struts2 springMVC hibernate
price:99.25
pic:6546545656.jpg
description:null
==================================
上一篇: lucene 的分词StandardAnalyzer
下一篇: lucene分词