美文网首页
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