前面几个文章也有用过查询, 这里说一下查询里面的一些 API.
- QueryParser 单一字段的查询解析器.
- MultiFieldQueryParser 多字段的查询解析器
- TermQuery 词条查询
- WildcardQuery 通配符查询
- FuzzyQuery 模糊查询
- newRangeQuery 范围查询
在学习之前, 先抽取一个方法, 不然总是写一些重复的代码.
创建一个初始化的.
再创建一个打印结果的.
Directory mDirectory;
IndexWriter indexWriter;
IndexReader indexReader;
IndexSearcher indexSearcher;
@Before
public void init() throws Exception {
//1. 创建一个 Director 对象, 指定索引库保存的位置.把索引保存在磁盘
mDirectory = FSDirectory.open(new File("/Users/yzhang/Desktop/Director").toPath());
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
indexWriter = new IndexWriter(mDirectory, indexWriterConfig);
indexReader = DirectoryReader.open(mDirectory);
//创建一个 indexSearch 对象, 构造方法中的参数就是 indexReader 对象.
indexSearcher = new IndexSearcher(indexReader);
}
private void printResult(Query query) throws Exception {
//执行查询, 得到一个 TopDocs 对象, 10 是指查询结果返回的最大记录数
TopDocs topDocs = indexSearcher.search(query, 10);
System.out.println("总记录数:" + topDocs.totalHits);
//取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//打印文档中的内容
for (ScoreDoc scoreDoc : scoreDocs) {
//取文档 ID
int docID = scoreDoc.doc;
//根据文档 ID 取文档对象
Document document = indexSearcher.doc(docID);
System.out.println("name:" + document.get("name"));
System.out.println("path:" + document.get("path"));
//System.out.println("content:" + document.get("content"));
System.out.println("size:" + document.get("size"));
System.out.println("\n--------------------------------------------------------\n");
}
//关闭 IndexReader 对象
indexReader.close();
}
TopDocs 查询结果对象
通过 IndexSearcher 对象, 获得 TopDocs 对象,
TopDocs 中包含两部分信息,
- int totalHits: 查询到的总记录数
- ScoreDoc [ ] scoreDocs: 文档列表
ScoreDooc 文档列表
包含两部分数据
- int doc: 文档的编号, 是 Lucene 给文档的唯一 ID.
- float score: 文档的信息
通过 文档编号 向 indexSearcher 拿真正的文档信息
1. QueryParser
可以对要查询的内容先分词, 然后基于分词的结果进行查询.
需要引入依赖
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>8.4.1</version>
</dependency>
使用.
@Test
public void testQueryParser()throws Exception{
//创建一个 QeuryParser 对象.两个参数
//参数 1: 指定默认搜索域
//参数 2: 分析器对象
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
//使用 queryParsr 创建一个 Query 对象
Query query = queryParser.parse("lucene 是一个 java 开发的全文检索工具包");
printResult(query);
}
2. MultiFieldQueryParser
多字段的查询
@Test
public void testMultiFieldQueryParser()throws Exception{
//查询name 域, content 域中包含 spring 关键字的文档.
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(new String[]{"name","content"}, new IKAnalyzer());
Query query = multiFieldQueryParser.parse("spring");
printResult(query);
}
3. TermQuery
词条查询.
- Term 是数据分词后得到的每一个词. 是分词的最小单位, 不能继续分.
- 值必须是字符串
- 使用场景: 通常查询一些不需要分词的, 例如 ID, 订单号, 证件号等.
@Test
public void testTermQuery() throws Exception {
// 创建词条查询对象
Query query = new TermQuery(new Term("", "spring"));
printResult(query);
}
4. WildcardQuery
通配符查询
- ? 可以代表任意一个字符
- * 表示多个任意字符.
- 案例: 查询 name 域中 h字符前面只能有一个任意字符, 后面有任意多个字符的文档.
@Test
public void testWildCardQuery() throws Exception {
// 创建查询对象
Query query = new WildcardQuery(new Term("name", "?h*"));
printResult(query);
}
5. FuzzyQuery
模糊查询
- 参数 1: Term 对象
- 参数 2: 允许用户输错, 但是要求错误的最大编辑距离在 0~2 之间.
(编辑距离: 一个单词到另一个单词最少要修改的次数, 例: googlo --> google 需要编辑 1 次, 那么编辑的距离就是 1, 错几个,编辑的距离就是几)
@Test
public void testFuzzyQuery() throws Exception {
Query query = new FuzzyQuery(new Term("name","sprink"),1);
printResult(query);
}
6. newRangeQuery
范围查询.
- 参数 1: 要查询的字段名称
- 参数 2: 最小值
- 参数 3: 最大值
- 案例: 查找 size 域 大于 0 小于 100 的文档
@Test
public void testRangeQuery() throws Exception {
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Query query = LongPoint.newRangeQuery("size", 0l, 100l);
printResult(query);
indexReader.close();
}
我所学习到的几个查询都在这里了, 后面有看到或者用到的,会继续补充.
网友评论