lucene 例子入门

全文搜索Lucene

什么是全文检索
 -这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search) 。

什么是Lucene
 -是Apache开源的一个专门用来实现全文检索的一个套类库,就是一些jar包

全文检索的应用场景

  1、搜索引擎    百度  谷歌  360  搜狗  
  2、站内搜索    微博  京东  猫扑 天涯
  3、垂直搜索    在优酷中搜索有可能数据是从芒果TV 搜狐视频 腾讯视频来的
数据的分类
   1、结构化数据 :有固定格式和有限长度 举例:mysql数据库表中的的数据
             查询方式:写sql
         数据量特别大时:
          使用SQL语句不可以:1、查询效率低
                             2、查询的关键字有可能需要分词 小米6X 128G         
         使用全文检索的方案
   2、非结构化数据:没有固定格式和长度  举例:电脑上的word Excel txt
             查询方式:目测
             数据量比较多时:使用流
         数据量特别大时:使用全文检索的方案

如何使用Lucene(理论)
    创建索引的步骤
      1、获取原始文档      
      2、构建文档对象 Document
      3、文档分词
      4、构建索引

    查询索引的步骤
      1、创建用户查询接口  创建一个能让用户输入关键字的位置
      2、创建查询      
      3、执行查询
      4、渲染查询结果  高亮显示结果

lucene 例子入门

 

准备:依赖

<dependencies>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- Junit单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- lucene核心库 -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>4.10.2</version>
        </dependency>
        <!-- Lucene的查询解析器 -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>4.10.2</version>
        </dependency>
        <!-- lucene的默认分词器库 -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>4.10.2</version>
        </dependency>
        <!--ik分词器-->
        <dependency>
            <groupId>com.janeluo</groupId>
            <artifactId>ikanalyzer</artifactId>
            <version>2012_u6</version>
        </dependency>

        <!-- lucene的高亮显示 -->
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-highlighter</artifactId>
            <version>4.10.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

创建索引

 //创建索引
    @Test
    public void testCreat() throws Exception{
        //指定索引库的位置
        Directory directory = FSDirectory.open(new File("D:\\lucene\\1"));
        //创建分词器 StandardAnalyzer()
        IKAnalyzer analyzer = new IKAnalyzer();
        //配置 版本(Version.LATEST 最新) 分词器
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);

        //创建索引的写出工具类。参数:索引的目录和配置信息
        IndexWriter indexWriter = new IndexWriter(directory,config);
//        修改索引。参数:
//         * 	词条:根据这个词条匹配到的所有文档都会被修改
//                * 	文档信息:要修改的新的文档数据
        //indexWriter.updateDocument(new Term("fileName","1"),new Document().add(new TextField("id","1", Field.Store.YES)));更新
        //indexWriter.deleteAll();//删除索引库
        //indexWriter.deleteDocuments(new Term("fileName","spring"));根据词条进行删除, 词条的数据类型必须是字符串
        //根据query对象删除,如果ID是数值类型,那么我们可以用数值范围查询锁定一个具体的ID
//        NumericRangeQuery<Long> fileSize1 = NumericRangeQuery.newLongRange("fileSize", 100L, 500L, true, true);
//        indexWriter.deleteDocuments(fileSize1);


        /*读取文件 创建文档对象*/
        //读取文件夹
        File fileDirectoryPath = new File("D:\\lucene\\资料\\查询资料searchsource");
        //获得文件夹的文件
        File[] files = fileDirectoryPath.listFiles();
        for (File file : files) {
            //创建文档对象
            Document document = new Document();
            //得到文件名
            String fileName = file.getName();
            // 创建并添加字段信息。参数:字段的名称、字段的值、是否存储,这里选Store.YES代表存储到文档列表。Store.NO代表不存储
            document.add(new TextField("fileName",fileName, Field.Store.YES));//存文件名
            //内容fileContent file转string
            String fileContent = FileUtils.readFileToString(file, "utf-8");
            document.add(new TextField("fileContent",fileContent, Field.Store.YES));
            //文件大小 fileSize
            long fileSize = FileUtils.sizeOf(file);//单位是byte字节
            document.add(new LongField("fileSize",fileSize, Field.Store.YES));
            //文件路径 filePath  StringField不分词
            String filePath = file.getPath();
            document.add(new StringField("filePath",filePath, Field.Store.YES));
            // 把文档交给IndexWriter
            indexWriter.addDocument(document);
        }
        indexWriter.close();
    }

查询索引 以及分页 排序 高亮

 //查询索引
    @Test
    public void testSearch() throws Exception{
        //指定索引库的位置
        Directory directory = FSDirectory.open(new File("D:\\lucene\\1"));
        //创建用户读取索引的对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        /*使用term查询*/
        //Query query = new TermQuery(new Term("fileName","简介"));
        /*查询所有*/
        //MatchAllDocsQuery query = new MatchAllDocsQuery();
        /*通配符查询*/
        //WildcardQuery query = new WildcardQuery(new Term("fileName", "*介*"));
        /*组合查询*/
//        BooleanQuery query = new BooleanQuery();
//        query.add(new TermQuery(new Term("fileName","apache")), BooleanClause.Occur.MUST);//必须有的
//        query.add(new TermQuery(new Term("fileContent","apache")), BooleanClause.Occur.SHOULD);//不必须有的
        /*范围查询*/ //ture是闭区间的意思
        //  NumericRangeQuery<Long> query = NumericRangeQuery.newLongRange("fileSize", 100L, 500L, true, true);
        /*分词查询*/
//        QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer());
//        Query query = queryParser.parse("spring is a good project");
        /*多域查询*/
        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(new String[]{"fileName", "fileContent"}, new IKAnalyzer());
        Query query = multiFieldQueryParser.parse("spring is a good project");
        query.setBoost(10);//竞价排序 打分 默认是1
        TopDocs topDocs = indexSearcher.search(query, 100);//按照匹配度排名得分前N名的文档信息


        //获得命中的文档对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            int doc = scoreDoc.doc;//获取文档id
            Document document = indexSearcher.doc(doc);//根据id查出文档
            System.out.println( "fileName:"+ document.get("fileName"));
            System.out.println( "fileSize:"+ document.get("fileSize"));
            System.out.println( "filePath:"+ document.get("filePath"));
            System.out.println( "fileContent:"+ document.get("fileContent"));
            System.out.println("------------------------------------------------------------------------");
        }
        indexReader.close();
    }



    //实现高亮
    @Test
    public void testHighlighter() throws Exception{
        //指定索引库的位置
        Directory directory = FSDirectory.open(new File("D:\\lucene\\1"));
        //创建用户读取索引的对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        /*使用term查询*/
        Query query = new TermQuery(new Term("fileName","简介"));
 /*高亮*/
        //格式化器
        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<em>", "</em>");
        QueryScorer queryScorer = new QueryScorer(query);
        //准备高亮工具
        Highlighter highlighter = new Highlighter(formatter,queryScorer);

        //搜索
        TopDocs topDocs = indexSearcher.search(query, 100);//按照匹配度排名得分前N名的文档信息
        //个数
        System.out.println("本次共搜索到:"+topDocs.totalHits);

        //获得命中的文档对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            int doc = scoreDoc.doc;//获取文档编号
            Document document = indexSearcher.doc(doc);//根据id查出文档
            // 用高亮工具处理普通的查询结果,参数:分词器,要高亮的字段的名称,高亮字段的原始值
            String fileName = document.get("fileName");
            highlighter.getBestFragment(new IKAnalyzer(),"fileName",fileName);
            System.out.println( "fileName:"+fileName);
            System.out.println( "fileSize:"+ document.get("fileSize"));
            System.out.println( "filePath:"+ document.get("filePath"));
            System.out.println( "fileContent:"+ document.get("fileContent"));
            System.out.println("------------------------------------------------------------------------");
        }
        indexReader.close();
    }

    //实现排序
    @Test
    public void testSortQuery() throws Exception{
        //指定索引库的位置
        Directory directory = FSDirectory.open(new File("D:\\lucene\\1"));
        //创建用户读取索引的对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        /*使用term查询*/
        Query query = new TermQuery(new Term("fileName","spring"));

        // 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
        Sort sort = new Sort(new SortField("fileName", SortField.Type.STRING, false));

        //搜索
        TopDocs topDocs = indexSearcher.search(query, 100,sort);//按照匹配度排名得分前N名的文档信息
        //个数
        System.out.println("本次共搜索到:"+topDocs.totalHits);

        //获得命中的文档对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            int doc = scoreDoc.doc;//获取文档编号
            Document document = indexSearcher.doc(doc);//根据id查出文档
            String fileName = document.get("fileName");
            System.out.println( "fileName:"+fileName);
            System.out.println("------------------------------------------------------------------------");
        }
        indexReader.close();
    }


    //实现分页
    @Test
    public void testPageQuery() throws Exception{
        // 实际上Lucene本身不支持分页。因此我们需要自己进行逻辑分页。我们要准备分页参数:
        int pageSize = 2;// 每页条数
        int pageNum = 3;// 当前页码
        int start = (pageNum - 1) * pageSize;// 当前页的起始条数
        int end = start + pageSize;// 当前页的结束条数(不能包含)

        //指定索引库的位置
        Directory directory = FSDirectory.open(new File("D:\\lucene\\1"));
        //创建用户读取索引的对象
        IndexReader indexReader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        /*分词查询*/
        QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer());
        Query query = queryParser.parse("spring is a good project");

        // 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
        Sort sort = new Sort(new SortField("fileName", SortField.Type.STRING, false));

        //搜索,查询0~end条
        TopDocs topDocs = indexSearcher.search(query, 100,sort);//按照匹配度排名得分前N名的文档信息
        //个数
        System.out.println("本次共搜索到:"+topDocs.totalHits);

        //获得命中的文档对象
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (int i=start;i<end&&i<scoreDocs.length;i++) {
            ScoreDoc doc = scoreDocs[i];//获取文档
            int docID = doc.doc;//获得id
            Document document = indexSearcher.doc(docID);//根据id查出文档
            String fileName = document.get("fileName");
            System.out.println( "fileName:"+fileName);
            System.out.println("------------------------------------------------------------------------");
        }
        indexReader.close();
    }



可以使用luke查看添加的索引。

lucene 例子入门

以上代码看不到具体体现

lucene 例子入门

 


lucene 例子入门

 

上一篇:Lucene索引库的维护功能实现


下一篇:Lucene全文检索入门使用