Lucene入门程序-Java API的简单使用

Lucene入门程序

准备环境

JDK: 1.8.0_162

IDE: Eclipse Neon.3

数据库: MySQL 5.7.20

Lucene: 4.10.4(已经很稳定了,高版本对部分分词器支持不好)

准备数据

SET FOREIGN_KEY_CHECKS=0;

--------------------------------
Table structure for `book`
--------------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (?
   `id` int(11) DEFAULT NULL,?
   `bookname` varchar(500) DEFAULT NULL,?
   `price` float DEFAULT NULL,?
   `pic` varchar(200) DEFAULT NULL,?
   `bookdesc` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--------------------------------
Records of book
--------------------------------
INSERT INTO `book` VALUES ('1', 'java从入门到精通', '56', '1.jpg', '《Java从入门到精通》是人民邮电出版社于 2010年出版的图书, 由国家863中部软件孵化器主编. 以零基础讲解为宗旨, 深入浅出地讲解Java的各项技术及实战技能. 本书从初学者角度出发, 通过通俗易懂的语言、丰富多彩的实例, 详细介绍了使用Java语言进行程序开发应该掌握的各方面技术. 全书共分28章, 包括: 初识Java, 熟悉Eclipse开发工具, Java 语言基础, 流程控制, 字符串, 数组, 类和对象, 包装类, 数字处理类, 接口、继承与多态, 类的高级特性, 异常处理, Swing程序设计, 集合类, I/O输入输出, 反射, 枚举类型与泛型, 多线程, 网络通信, 数据库操作, Swing表格组件, Swing树组件, Swing其他高级组件, 高级布局管理器, 高级事件处理, AWT绘图与音频播放, 打印技术和企业进销存管理系统等. 所有知识都结合具体实例进行介绍, 涉及的程序代码给出了详细的注释, 可以使读者轻松领会Java程序开发的精髓, 快速提高开发技能. ');
INSERT INTO `book` VALUES ('2', 'java web开发', '80', '2.jpg', 'Java Web, 是用Java技术来解决相关web互联网领域的技术总和. web包括: web服务器和web客户端两部分. Java在客户端的应用有java applet, 不过使用得很少, Java在服务器端的应用非常的丰富, 比如Servlet, JSP和第三方框架等等. Java技术对Web领域的发展注入了强大的动力. ');
INSERT INTO `book` VALUES ('3', 'lucene从入门到精通', '100', '3.jpg', '本书总结搜索引擎相关理论与实际解决方案, 并给出了 Java 实现, 其中利用了流行的开源项目Lucene和Solr, 而且还包括原创的实现. 本书主要包括总体介绍部分、爬虫部分、自然语言处理部分、全文检索部分以及相关案例分析. 爬虫部分介绍了网页遍历方法和如何实现增量抓取, 并介绍了从网页等各种格式的文档中提取主要内容的方法. 自然语言处理部分从统计机器学习的原理出发, 包括了中文分词与词性标注的理论与实现以及在搜索引擎中的实用等细节, 同时对文档排重、文本分类、自动聚类、句法分析树、拼写检查等自然语言处理领域的经典问题进行了深入浅出的介绍并总结了实现方法. 在全文检索部分, 结合Lucene 3.0介绍了搜索引擎的原理与进展. 用简单的例子介绍了Lucene的最新应用方法. 本书包括完整的搜索实现过程: 从完成索引到搜索用户界面的实现. 本书还进一步介绍了实现准实时搜索的方法, 展示了Solr 1.4版本的用法以及实现分布式搜索服务集群的方法. 最后介绍了在地理信息系统领域和户外活动搜索领域的应用. ');
INSERT INTO `book` VALUES ('4', 'lucene in action', '90', '4.jpg', '本书深入浅出地介绍了lucene——一个开源的使用java语言编写的全文搜索引擎开发包. 它通过浅显的语言、大量的图注、丰富的代码示例, 以及清晰的结构为读者呈现出作为优秀开源项目的lucene所体现的强大功能. 全书共10章, 分为两大部分. 第1部分lucene的核心, 着重于lucene的核心 api介绍, 并按照把lucene集成到程序中的顺序宋组织;第2部分lucene的应用, 通过对lucene内置工具的介绍, 展示了lucene技术的高级应用和在各种程序语言上的移植. ');
INSERT INTO `book` VALUES ('5', 'Lucene Java精华版', '80', '5.jpg', '本书总结搜索引擎相关理论与实际解决方案, 并给出了 Java 实现, 其中利用了流行的开源项目Lucene和Solr, 而且还包括原创的实现. 本书主要包括总体介绍部分、爬虫部分、自然语言处理部分、全文检索部分以及相关案例分析. 爬虫部分介绍了网页遍历方法和如何实现增量抓取, 并介绍了从网页等各种格式的文档中提取主要内容的方法. 自然语言处理部分从统计机器学习的原理出发, 包括了中文分词与词性标注的理论与实现以及在搜索引擎中的实用等细节, 同时对文档排重、文本分类、自动聚类、句法分析树、拼写检查等自然语言处理领域的经典问题进行了深入浅出的介绍并总结了实现方法. 在全文检索部分, 结合Lucene 3.0介绍了搜索引擎的原理与进展. 用简单的例子介绍了Lucene的最新应用方法. 本书包括完整的搜索实现过程: 从完成索引到搜索用户界面的实现. 本书还进一步介绍了实现准实时搜索的方法, 展示了Solr 1.4版本的用法以及实现分布式搜索服务集群的方法. 最后介绍了在地理信息系统领域和户外活动搜索领域的应用. ');

创建工程

创建Maven Project(打包方式选jar即可)

配置pom.xml, 导入依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.healchow</groupId>
  <artifactId>lucene-first</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>lucene-first</name>
  <url>http://maven.apache.org</url>

  <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <!-- mysql版本 -->
       <mysql.version>5.1.44</mysql.version>
       <!-- lucene版本 -->
       <lucene.version>4.10.4</lucene.version>
  </properties>

  <dependencies>
       <!-- mysql数据库依赖 -->
       <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
       </dependency>
       <!-- lucene依赖包 -->
       <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>${lucene.version}</version>
       </dependency>
       <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>${lucene.version}</version>
       </dependency>
       <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>${lucene.version}</version>
       </dependency>
       <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
       </dependency>
  </dependencies>
</project> 

准备原始数据采集

准备图书POJO

public class Book {
    private Integer id;       // int(11) DEFAULT NULL,
    private String bookname;  // varchar(500) DEFAULT NULL,
    private Float price;      // float DEFAULT NULL,
    private String pic;       // varchar(200) DEFAULT NULL,
    private String bookdesc;  // varchar(2000) DEFAULT NULL

    // Getters/Setters

    @Override
    public String toString() {
        return "Book [id=" + id + ", bookname=" + bookname +
            ", price=" + price + ", pic=" + pic +
            ", bookdesc=" + bookdesc + "]";
    }
}

准备图书DAO接口

public interface BookDao {
    /**
     * 查询全部图书
     */
    List<Book> queryBookList();
}

实现图书DAO接口

public class BookDaoImpl implements BookDao {
    /**
     * 查询全部图书
     */
    public List<Book> listAll() {
        // 创建图书结果集合List
        List<Book> books = new ArrayList<Book>();

        Connection conn = null;
        PreparedStatement preStatement = null;
        ResultSet resultSet = null;

        try {
            // 加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 创建数据库连接对象
            conn = DriverManager.getConnection(
                       "jdbc:mysql://127.0.0.1:3306/lucene?useSSL=true",
                       "root",
                       "password");

            // 定义查询SQL
            String sql = "select * from book";
            // 创建Statement语句对象
            preStatement = conn.prepareStatement(sql);
            // 执行语句, 得到结果集
            resultSet = preStatement.executeQuery();

            // 处理结果集
            while (resultSet.next()) {
                 // 创建图书对象
                 Book book = new Book();
                 book.setId(resultSet.getInt("id"));
                 book.setBookname(resultSet.getString("bookname"));
                 book.setPrice(resultSet.getFloat("price"));
                 book.setPic(resultSet.getString("pic"));
                 book.setBookdesc(resultSet.getString("bookdesc"));
                 // 将查询到的结果添加到list中
                 books.add(book);
            }
       } catch (Exception e) {
            e.printStackTrace();
       } finally {
            // 释放资源
            try {
                 if (null != conn) conn.close();
                 if (null != preStatement) preStatement.close();
                 if (null != resultSet) resultSet.close();
            } catch (Exception e) {
                 e.printStackTrace();
            }
        }
        return books;
    }

    /**
     * 测试功能的主方法
     */
    public static void main(String[] args) {
        // 创建图书Dao的实现对象
        BookDao bookDao = new BookDaoImpl();
        List<Book> books = bookDao.listAll();

        // 如果结果不为空, 则便利输出
        for (Book book : books) {
            System.out.println(book);
        }
    }
}

测试结果如下:

索引流程的实现

  1. 采集原始数据;
  2. 创建文档对象(Document);
  3. 创建分析器对象(Analyzer), 用于分词;
  4. 创建索引配置对象(IndexWriterConfig), 用于配置Lucene;
  5. 创建索引库目录位置对象(Directory), 指定索引库的存储位置;
  6. 创建索引写入对象(IndexWriter), 将文档对象写入索引库;
  7. 使用IndexWriter对象, 创建索引;
  8. 释放资源.

示例代码

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class IndexManager {
    /**
     * 创建索引功能的测试
     * @throws Exception
     */
    @Test
    public void createIndex() throws IOException{
        // 1. 采集数据
        BookDao bookDao = new BookDaoImpl();
        List<Book> books = bookDao.listAll();

        // 2. 创建文档对象
        List<Document> documents = new ArrayList<Document>();
        for (Book book : books) {
            Document document = new Document();
            // 给文档对象添加域
            // add方法: 把域添加到文档对象中, field参数: 要添加的域
            // TextField: 文本域, 属性name:域的名称, value:域的值, store:指定是否将域值保存到文档中
            document.add(new TextField("bookId", book.getId() + "", Store.YES));
            document.add(new TextField("bookName", book.getBookname(), Store.YES));
            document.add(new TextField("bookPrice", book.getPrice() + "", Store.YES));
            document.add(new TextField("bookPic", book.getPic(), Store.YES));
            document.add(new TextField("bookDesc", book.getBookdesc(), Store.YES));

            // 将文档对象添加到文档对象集合中
            documents.add(document);
        }
        // 3. 创建分析器对象(Analyzer), 用于分词
        Analyzer analyzer = new StandardAnalyzer();
        // 4. 创建索引配置对象(IndexWriterConfig), 用于配置Lucene
        // 参数一:当前使用的Lucene版本, 参数二:分析器
        IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
        // 5. 创建索引库目录位置对象(Directory), 指定索引库的存储位置
        File path = new File("/your_path/index");
        Directory directory = FSDirectory.open(path);
        // 6. 创建索引写入对象(IndexWriter), 将文档对象写入索引
        IndexWriter indexWriter = new IndexWriter(directory, indexConfig);
        // 7. 使用IndexWriter对象创建索引
        for (Document doc : documents) {
            // addDocement(doc): 将文档对象写入索引库
            indexWriter.addDocument(doc);
        }
        // 8. 释放资源
        indexWriter.close();
    }
}

测试结果

说明: 只要看到以下文件, 说明索引已经创建成功了:

使用Luke工具查看索引

使用说明

Windows OS下,双击运行start.bat文件(前提是需要配置jdk的环境变量);

Mac OS下, 在终端中进入当前目录, 然后键入 ./start.sh 即可运行.

运行界面一

运行界面二

运行界面三

检索流程的实现

  1. 创建分析器对象(Analyzer), 用于分词;
  2. 创建查询对象(Query);
  3. 创建索引库目录位置对象(Directory), 指定索引库的位置;
  4. 创建索引读取对象(IndexReader), 用于读取索引;
  5. 创建索引搜索对象(IndexSearcher), 用于执行搜索;
  6. 使用IndexSearcher对象, 执行搜索, 返回搜索结果集TopDocs;
  7. 处理结果集;
  8. 释放资源.

使用Luke工具搜索

bookName:lucene -- 表示搜索bookName域中包含有lucene.

示例代码

/**
 * 检索索引功能的测试
 * @throws Exception
 */
@Test
public void searchIndexTest() throws Exception {
    // 1. 创建分析器对象(Analyzer), 用于分词
    Analyzer analyzer = new StandardAnalyzer();

    // 2. 创建查询对象(Query)
    // 2.1 创建查询解析器对象
    // 参数一:默认的搜索域, 参数二:使用的分析器
    QueryParser queryParser = new QueryParser("bookName", analyzer);
    // 2.2 使用查询解析器对象, 实例化Query对象
    Query query = queryParser.parse("bookName:lucene");

    // 3. 创建索引库目录位置对象(Directory), 指定索引库位置
    Directory directory = FSDirectory.open(new File("/your_path/index"));

    // 4. 创建索引读取对象(IndexReader), 用于读取索引
    IndexReader indexReader = DirectoryReader.open(directory);

    // 5. 创建索引搜索对象(IndexSearcher), 用于执行索引
    IndexSearcher searcher = new IndexSearcher(indexReader);

    // 6. 使用IndexSearcher对象执行搜索, 返回搜索结果集TopDocs
    // 参数一:使用的查询对象, 参数二:指定要返回的搜索结果排序后的前n个
    TopDocs topDocs = searcher.search(query, 10);

    // 7. 处理结果集
    // 7.1 打印实际查询到的结果数量
    System.out.println("实际查询到的结果数量: " + topDocs.totalHits);
    // 7.2 获取搜索的结果数组
    // ScoreDoc中有文档的id及其评分
    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    for (ScoreDoc scoreDoc : scoreDocs) {
        System.out.println("= = = = = = = = = = = = = = = = = = =");
        // 获取文档的id和评分
        int docId = scoreDoc.doc;
        float score = scoreDoc.score;
        System.out.println("文档id= " + docId + " , 评分= " + score);
        // 根据文档Id, 查询文档数据 -- 相当于关系数据库中根据主键Id查询数据
        Document doc = searcher.doc(docId);
        System.out.println("图书Id: " + doc.get("bookId"));
        System.out.println("图书名称: " + doc.get("bookName"));
        System.out.println("图书价格: " + doc.get("bookPrice"));
        System.out.println("图书图片: " + doc.get("bookPic"));
        System.out.println("图书描述: " + doc.get("bookDesc"));
    }

    // 8. 关闭资源
    indexReader.close();
}

测试结果

结果说明

  1. 索引库中包含索引域和文档域;
  2. 索引域保存索引数据(倒排索引), 用于索引;
  3. 文档域中保存文档数据, 用于搜索获取数据.

IndexSearcher方法

方法 说明
indexSearcher.search(query, n) 根据Query搜索, 返回评分最高的n条记录
indexSearcher.search(query,filter,n) 根据Query搜索, 添加过滤策略, 返回评分最高的n条记录
indexSearcher.search(query, n, sort) 根据Query搜索, 添加排序策略, 返回评分最高的n条记录
indexSearcher.search(booleanQuery, filter, n, sort) 根据Query搜索, 添加过滤策略, 添加排序策略, 返回评分最高的n条记录

版权声明

作者: ma_shoufeng(马瘦风)

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但未经博主同意必须保留此段声明, 且在文章页面明显位置给出原文链接, 否则博主保留追究法律责任的权利.

原文地址:https://www.cnblogs.com/shoufeng/p/9367789.html

时间: 2024-10-25 21:40:53

Lucene入门程序-Java API的简单使用的相关文章

1.2 lucene入门程序环境搭建及入门代码

 lucene入门程序环境搭建及入门代码 1.1      需求 使用lucene完成对数据库中图书信息的索引和搜索功能. 1.2      环境准备 l  Jdk:1.7及以上 l  Lucene:4.10(从4.8版本以后,必须使用jdk1.7及以上) l  Ide:indigo l  数据库:mysql 5 1.3      工程搭建 l  Mysql驱动包 l  Analysis的包 l  Core包 l  QueryParser包 l  Junit包(非必须) 创建po类 1 publ

Elasticsearch java api 基本搜索部分详解

版权声明:本文非原创文章,转载出处:http://blog.csdn.net/molong1208/article/details/50512149 一.所使用版本的介绍 使用的是elasticsearch2.1.0版本,在此只是简单介绍搜索部分的api使用 二.简单的搜索 使用api的时候,基本上可以将DSL搜索的所有情况均写出来,在此给出一个最简单搜索的全部的过程以及代码,之后将对不同的搜索只是针对函数进行介绍 (1)DSL搜索 对于最简单的DSL搜索,对一个词进行搜索使用url直接进行通信

大数据技术之_20_Elasticsearch学习_01_概述 + 快速入门 + Java API 操作 + 创建、删除索引 + 新建、搜索、更新删除文档 + 条件查询 + 映射操作

一 概述1.1 什么是搜索?1.2 如果用数据库做搜索会怎么样?1.3 什么是全文检索和 Lucene?1.4 什么是 Elasticsearch?1.5 Elasticsearch 的适用场景1.6 Elasticsearch 的特点1.7 Elasticsearch 的核心概念1.7.1 近实时1.7.2 Cluster(集群)1.7.3 Node(节点)1.7.4 Index(索引 --> 数据库)1.7.5 Type(类型 --> 表)1.7.6 Document(文档 -->

_00017 Kafka的体系结构介绍以及Kafka入门案例(初级案例+Java API的使用)

博文作者:妳那伊抹微笑 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前,妳却感觉不到我的存在 技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术 转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作! qq交流群:214293307  (期待与你一起学习,共同进步) # Kfaka的体系结构 # 学习前言 Kafka的整个学习过程就是自己看官网的文档,出

Java的多线程 简单入门

Java的多线程 简单入门 首先可以先搞清楚什么是程序.进程.线程,以及它们之间的关系: 定义: 一 程序只是一组指令的有序集合,它是静态的 二 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位: 三 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程: 进程与线程区别与联系 (

RPC学习----Thrift快速入门和Java简单示例

一.什么是RPC? RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据.在OSI网络通信模型中,RPC跨越了传输层和应用层.RPC使得开发包括网络分布式多程序在内的应用程序更加容易. 二.什么是Thrift? thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和

_00019 Storm的体系结构介绍以及Storm入门案例(官网上的简单Java案例)

博文作者:妳那伊抹微笑 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前,妳却感觉不到我的存在 技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术 转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作! qq交流群:214293307  (期待与你一起学习,共同进步) # Storm

利用Hadoop提供的RPC API实现简单的RPC程序

[toc] 利用Hadoop提供的RPC API实现简单的RPC程序 在Hadoop中提供了RPC服务的使用API,通过其API地使用,可以非常简单地构建远程过程调用程序,下面就给出一个简单的实例. 项目结构 为了方便操作,所有的代码都放在本地一个项目中,实际上,完全可以将代码放在不同的服务器上,这是RPC的概念,这里就不做过多的介绍.项目结构如下: rpc/ ├── HelloServiceImpl.java ├── IHelloService.java ├── RPCClientDriver

MyBatis 介绍、简单入门程序

JDBC 编程中的问题 1. 将 SQL 语句硬编码到 Java 代码.不利于系统维护. 设想怎样解决:将SQL单独抽取出来,在配置文件(xml方式.properties文件)进行配置. 2. 数据库连接不能反复利用,对数据库资源是一中浪费. 设想怎样解决:使用数据库连接池管理数据库连接. 3. 向 Statement 设置參数时,对于參数的位置通过硬编码指定,不利于系统维护. 设想怎样解决:是否可以自己主动将 Java 对象的值设置到 Statement. 4. 遍历结果集.resultSet