美文网首页
Lucene 入门 07 - 索引库的查询(重点)

Lucene 入门 07 - 索引库的查询(重点)

作者: __Y_Q | 来源:发表于2020-01-16 17:16 被阅读0次

前面几个文章也有用过查询, 这里说一下查询里面的一些 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();
    }

我所学习到的几个查询都在这里了, 后面有看到或者用到的,会继续补充.

相关文章

网友评论

      本文标题:Lucene 入门 07 - 索引库的查询(重点)

      本文链接:https://www.haomeiwen.com/subject/bhnczctx.html