zoukankan      html  css  js  c++  java
  • Lucene入门

    Lucene快速入门:

      搭建环境

        1.创建工程,引入坐标(springboot工程)

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <skipTests>true</skipTests>
    </properties>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>7.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>7.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.7.2</version>
        </dependency>
    
        <!-- 测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- mysql数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    
        <!-- IK中文分词器 -->
        <dependency>
            <groupId>com.github.magese</groupId>
            <artifactId>ik-analyzer</artifactId>
            <version>8.1.0</version>
        </dependency>
    
        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 引入thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Json转换工具 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>
    </dependencies>

        2.创建数据库,准备百万条数据

          ..........

        3.在磁盘创建Lucene索引文件和文档文件的存放目录(索引库)

          

      索引流程

        1.数据采集

          在电商网站中,全文检索的数据源在数据库中,需要通过jdbc访问数据库中 sku 表的内容。

          创建pojo对象:

    public class Sku {
    
        //商品主键id
        private String id;
        //商品名称
        private String name;
        //价格
        private Double price;
        //库存数量
        private Integer num;
        //图片
        private String image;
        //分类名称
        private String categoryName;
        //品牌名称
        private String brandName;
        //规格
        private String spec;
        //销量
        private Integer saleNum;
    
        /********* get/set方法 *********/
    }

          创建DAO:

    public class SkuDao {
    
        public List<Sku> querySkuList() {
            // 数据库链接
            Connection connection = null;
            // 预编译statement
            PreparedStatement preparedStatement = null;
            // 结果集
            ResultSet resultSet = null;
            // 商品列表
            List<Sku> list = new ArrayList<Sku>();
    
            try {
                // 加载数据库驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 连接数据库
                connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/lucene", "root", "root");
                // SQL语句
                String sql = "SELECT * FROM tb_sku";
                // 创建preparedStatement
                preparedStatement = connection.prepareStatement(sql);
                // 获取结果集
                resultSet = preparedStatement.executeQuery();
                // 结果集解析
                while (resultSet.next()) {
                    Sku sku = new Sku();
                    sku.setId(resultSet.getString("id"));
                    sku.setName(resultSet.getString("name"));
                    sku.setSpec(resultSet.getString("spec"));
                    sku.setBrandName(resultSet.getString("brand_name"));
                    sku.setCategoryName(resultSet.getString("category_name"));
                    sku.setImage(resultSet.getString("image"));
                    sku.setNum(resultSet.getInt("num"));
                    sku.setPrice(resultSet.getDouble("price"));
                    sku.setSaleNum(resultSet.getInt("sale_num"));
                    list.add(sku);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return list;
        }
    }

        2.实现索引流程

    /**
     * 索引库维护
     */
    public class IndexManagerTest {
    
        /**
         * 创建索引库
         */
        @Test
        public void testCreateIndex() throws IOException {
            // 1. 采集数据
            SkuDao skuDao = new SkuDao();
            List<Sku> skus = skuDao.querySkuList();
    
            // 创建文档集合
            List<Document> docList = new ArrayList<>();
            // 2. 创建Document文档对象
            for (Sku sku : skus) {
                Document document = new Document();
    
                // 创建域对象,并且放入文档对象中
                document.add(new TextField("id", sku.getId(), TextField.Store.YES));
                document.add(new TextField("name", sku.getName(), TextField.Store.YES));
                document.add(new TextField("price", String.valueOf(sku.getPrice()), TextField.Store.YES));
                document.add(new TextField("image", sku.getImage(), TextField.Store.YES));
                document.add(new TextField("categoryName", sku.getCategoryName(), TextField.Store.YES));
                document.add(new TextField("brandName", sku.getBrandName(), TextField.Store.YES));
    
                // 将文档对象放入到文档集合中
                docList.add(document);
            }
            // 3. 创建分析器(分词器) StandardAnalyzer标准分词器,对英文分词效果好,对中文是单字分词
            Analyzer analyzer = new StandardAnalyzer();
            // 4. 创建IndexWriterConfig配置信息类,指定切分词使用的分词器
            IndexWriterConfig config = new IndexWriterConfig(analyzer);
            // 5. 创建Directory对象,声明索引库存储位置
            Directory dir = FSDirectory.open(Paths.get("D:\lucene"));
            // 6. 创建IndexWriter写入对象,指定写入的位置和使用的config初始化对象
            IndexWriter indexWriter = new IndexWriter(dir, config);
            // 7. 把Document写入到索引库中
            for (Document document : docList) {
                indexWriter.addDocument(document);
            }
            // 8. 释放资源
            indexWriter.close();
        }
    }

        3.执行效果:在文件夹中出现了以下文件,表示创建索引成功

          

      使用Luke查看索引:

        

         

         

       搜索流程:

        IndexSearcher搜索方法如下:

          

    /**
     * 测试搜索过程
     */
    public class SearchTest {
    
        @Test
        public void testSearch() throws ParseException, IOException {
            // 1.创建分词器(对搜索的关键词进行分词使用,分词器要和创建索引的时候使用的分词器一样)
            Analyzer analyzer = new StandardAnalyzer();
            // 2.创建Query搜索对象
            QueryParser queryParser = new QueryParser("name", analyzer);
            // 3.设置搜索关键词
            // Query query = queryParser.parse("华为手机");// 默认在name域中查
            Query query = queryParser.parse("brandName:生机谷");
            // 4.创建Directory目录对象,指定索引库位置
            Directory dir = FSDirectory.open(Paths.get("D:\lucene"));
            // 5.创建输入流对象
            IndexReader indexReader = DirectoryReader.open(dir);
            // 6.创建索引搜索对象IndexSearcher
            IndexSearcher searcher = new IndexSearcher(indexReader);
            // 7.使用索引搜索对象,执行搜索,返回结果集TopDocs
            // 第二个参数表示返回多少条数据用于展示,分页使用
            TopDocs topDocs = searcher.search(query, 10);
            // 获取查询到的结果集总数
            long total = topDocs.totalHits;
            System.out.println(total);
            // 8.获取结果集
            ScoreDoc[] docs = topDocs.scoreDocs;
            // 9.解析结果集
            if(docs != null) {
                for (ScoreDoc scoreDoc : docs) {
                    // 获取查询到的文档唯一标识,文档id,这个id是Lucene在创建文档的时候自动分配的
                    int docID = scoreDoc.doc;
                    // 通过文档id读取文档
                    Document doc = searcher.doc(docID);
                    System.out.println("-------------------");
                    // 通过域名,从文档中获取域值
                    System.out.println("id:" + doc.get("id"));
                    System.out.println("name:" + doc.get("name"));
                    System.out.println("price:" + doc.get("price"));
                    System.out.println("image:" + doc.get("image"));
                    System.out.println("categoryName:" + doc.get("categoryName"));
                    System.out.println("brandName:" + doc.get("brandName"));
                }
            }
            // 10.释放资源
            indexReader.close();
        }
    }
  • 相关阅读:
    二分图之最小边覆盖(poj3020)
    第一章:计算机网络概述
    X Window 简单的新手教程
    SharePoint Permission Analyzer 权限分析仪
    《源创新》:破坏性创新换了个说法,有陷入锤子钉子模式的嫌疑,书中的案例可以看一看。
    《金融可以颠覆历史》:隐藏在历史事件背后的金融制度发展历程
    转发:三伏天话“三伏贴”
    《浪潮之巅》(第2版):精彩的IT商战史
    《史玉柱自述》:管理者要谦虚,好的经营策略是试出来的
    《生活中的经济学》:主张让市场去解决生活中的问题,离中国的现实有点远
  • 原文地址:https://www.cnblogs.com/roadlandscape/p/12547143.html
Copyright © 2011-2022 走看看