[连载]Java程序设计(03)---任务驱动方式:寻找高富帅和屌丝

1. Sphin x简介

1.1. 什么是全文检索

全文检索是指以文档的全部文本信息作为检索对象的一种信息检索技术 。检索的对象有可能是文章的标题,也有可能是文章的作者,也有可能是文章摘要或内容。

1.2. 介绍

Sphin x是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能 ,使得应用程序更容易实现专业化的全文检索。Sphin x特别为一些脚本语言设计搜索API接口 ,如PHP ,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。

1.3. Sphin x的特性

高速索引 (在新款CPU上,近10 MB/秒);

高速搜索 (2-4G的文本量中平均查询速度不到0.1秒);

高可用性 (单CPU上最大可支持100 GB的文本,100M文档);

提供良好的相关性排名

支持分布式搜索;

提供文档摘要生成;

提供从MySQL内部的插件式存储引擎上搜索

supports boolean, phrase, and word proximity queries;

支持每个文档多个全文检索域(默认最大32个);

支持每个文档多属性;

支持断词;

支持单字节编码与UTF-8编码;

supports English stemming, Russian stemming, and Soundex for morphology;

支持MySQ(MyISAM和InnoDB 表都支持);

支持PostgreSQL.2. Sphin x安装(For MySQL) 2.1. Windows下安装 从http://dev.mysql .com/ 上下载MySQL5.0.45版安装配置好MySQL,采用utf-8字符 集

==================================================================================================================

要为站点提供自定义搜索功能,您必须有数据源和搜索该数据源的功能。对于 Web 应用程序,数据源通常是一个关系数据库,其中内置了一些搜索功能(Equality 是一个简单的搜索运算符,与 SQL 运算符
LIKE 一样)。但是,一些搜索可能比数据库可以执行的搜索更加具体,或者搜索可能过于复杂,而导致固有的 SQL JOIN 反应迟钝。

要加速搜索,您可以重新安排表,并由此简化底层查询(表和 SQL 查询优化高度依赖于模式和引擎。可通过在线搜索查找有关数据库性能的各种文章和书籍)。此外,您可以添加一个专门化的搜索引擎。应用哪种形式的搜索引擎还依赖于数据的形式(和数量)和预算。有许多选择可用:您可以将一个 Google 工具连接到您的络中,购买 Endeca 或其他大型商业搜索产品,或者尝试 Lucene。但是在很多情况下,使用商业产品都有点小题大做,或者浪费运营预算,并且 Lucene 在 2007 年 7 月编写时并未提供 PHP API。

作为一个备选方案,考虑一下 Sphinx,它是一种开源和免费的搜索引擎,可以非常快速地搜索文本。例如,在一个几乎有 300,000 行及五个索引列(每列包含大约 15 个单词)的活动数据库中,Sphinx 可以在 1/100 秒内得到 “这些单词中任何一个单词” 的搜索结果(在运行 Debian Linux? Sarge
的 2-GHz AMD Opteron 处理器、1 GB RAM 的计算机上)。

Sphinx 提供了大量功能,包括:

  • 它可以为能够表示为字符串的所有数据建立索引。
  • 它可以以各种方式为相同数据建立索引。对于多个索引,每个索引都针对特定目的而定制,您可以选择最适当的索引来优化搜索结果。
  • 它可以把属性与每条索引数据关联起来。然后您可以使用一个或多个属性来进一步过滤搜索结果。
  • 它支持词法,因此搜索单词 “cats” 还会找到词根 “cat”。
  • 您可以在许多计算机中分发 Sphinx 索引,从而提供故障恢复功能。
  • 它可以创建任意长度的单词前缀索引和可变长度的中缀子字符串的索引。例如,一个零件号可以是 10 个字符宽。前缀索引将匹配位于字符串开头处的所有可能的子字符串。中缀索引将匹配在字符串内任意位置的子字符串。
  • 您可以在 MySQL V5 内将其作为存储引擎运行,降低使用其他守护程序的需求(通常被视为另一个故障点)。

您可以在 Sphinx 源代码附带的 README 文件中或通过在线资料找到完整的功能列表。Sphinx Web 站点还列出了已经部署了 Sphinx 的若干个项目。

Sphinx 是用 C++ 编写、用 GNU 编译器构建、支持 64 位支持平台,并在 Linux、UNIX?、Microsoft? Windows? 和 Mac OS X 上运行。构建 Sphinx 十分简单:下载并解压缩代码,然后运行
./configure && make && make install 命令。

默认情况下,Sphinx 实用程序将被安装到 /usr/local/bin/ 中,并且所有 Sphinx 组件的配置文件都位于 /usr/local/etc/sphinx.conf 中。

Sphinx 有三个组件:索引生成器、搜索引擎和命令行 search 实用程序:

  • 索引生成器被称为索引器。它将查询数据库,为结果的每行中的每列建立索引,并且将每个索引条目绑定到行的主键上。
  • 搜索引擎是名为 searchd 的守护程序。该守护程序将接收搜索词和其他参数,快速遍历一个或多个索引,并返回结果。如果找到匹配,searchd 将返回一个主键数组。对于这些键,应用程序可以针对相关数据库运行查询来查找包含匹配的完整记录。Searchd 将在端口 3312 上通过套接字连接与应用程序进行通信。
  • 便捷的 search 实用程序使您可以从命令行构造搜索而无需编写代码。如果 searchd 返回匹配,则 search 将查询数据库并显示匹配集中的行。search 实用程序对于调试 Sphinx 配置和执行临时搜索十分有用。

集成 Sphinx 软件

要应用 Sphinx 来解决问题,您必须定义一个或多个数据源以及一个或多个索引。

source 将标识数据库来建立索引,提供验证信息,并且定义查询用以构造每行。数据源可以随意地标识一列或多列作为过滤器,Sphinx 将之称为。您将使用组来过滤结果。例如,单词描述可能得到 900 个匹配。如果只对特定型号的汽车匹配感兴趣,则可以进一步使用型号组进行过滤。

index 将要求获得数据源(即一组数据行)并定义应当如何为已从数据源中提取出来的数据编目。

您将在 sphinx.conf 文件中定义数据源和索引。Body Parts 的数据源是 MySQL 数据库。清单 5 显示了名为 catalog 的数据源的部分定义 —— 指定连接的数据库以及如何建立连接(主机、套接字、用户和密码)的代码片段。

清单 5. 用于访问 MySQL 数据库的设置

source catalog
{
    type                            = mysql

    sql_host                        = localhost
    sql_user                        = reaper
    sql_pass                        = s3cr3t
    sql_db                          = body_parts
    sql_sock                        =  /var/run/mysqld/mysqld.sock
    sql_port                        = 3306

接下来,创建一个查询以生成要被索引的行。通常,将创建 SELECT 子句,可能需要把许多表 JOIN 在一起才能得到行。但这里存在一个问题:搜索型号和年份必须使用 Assembly 表,但是零件号和零件描述只能在 Inventory 表中找到。为此,Sphinx 必须能够把搜索结果与 32 位整型主键绑定在一起。

要获得右侧表单中的数据,需要创建一个视图 —— MySQL V5 中的新结构,它将把来自其他表的列整合到单独的合成虚拟表中。使用视图,各类搜索所需的所有数据都在一个位置,但是活动数据实际上存在于其他表中。清单 6 显示了定义 Catalog 视图的 SQL。

清单 6. Catalog 视图将把数据整合到虚拟表中

CREATE OR REPLACE VIEW Catalog AS
SELECT
  Inventory.id,
  Inventory.partno,
  Inventory.description,
  Assembly.id AS assembly,
  Model.id AS model
FROM
  Assembly, Inventory, Model, Schematic
WHERE
  Schematic.partno_id=Inventory.id
  AND Schematic.model_id=Model.id
  AND Schematic.assembly_id=Assembly.id;

如果用前面所示的表和数据创建名为 body_parts 的数据库,则 Catalog 视图应当类似以下内容:

mysql> use body_parts;
Database changed
mysql> select * from Catalog;
+----+---------+---------------------+----------+-------+
| id | partno  | description         | assembly | model |
+----+---------+---------------------+----------+-------+
|  6 | 765432  | Bolt                |        5 |     1 |
|  8 | ENG088  | Cylinder head       |        5 |     1 |
|  1 | WIN408  | Portal window       |        3 |     1 |
|  5 | WIN958  | Windshield, front   |        3 |     1 |
|  4 | ACC5409 | Cigarette lighter   |        7 |     3 |
|  9 | ENG976  | Large cylinder head |        5 |     3 |
|  8 | ENG088  | Cylinder head       |        5 |     7 |
|  6 | 765432  | Bolt                |        5 |     7 |
+----+---------+---------------------+----------+-------+
8 rows in set (0.00 sec)

在视图中,字段 id 将指回 Inventory 表中的零件条目。partnodescription 列是要搜索的主要文本,而
assemblymodel 列用作进一步过滤结果的组。视图就绪后,构造数据源查询就是小事一桩。清单 7 显示了 catalog 数据源定义的其余部分。

清单 7. 查询创建待索引的行

    # indexer query
    # document_id MUST be the very first field
    # document_id MUST be positive (non-zero, non-negative)
    # document_id MUST fit into 32 bits
    # document_id MUST be unique
    sql_query                       = /
            SELECT /
                    id, partno, description, /
                    assembly, model /
            FROM /
                    Catalog;

    sql_group_column                = assembly
    sql_group_column                = model

    # document info query
    # ONLY used by search utility to display document information
    # MUST be able to fetch document info by its id, therefore
    # MUST contain ‘$id‘ macro
    #
    sql_query_info          = SELECT * FROM Inventory WHERE id=$id
}

sql_query 必须包括后续查找需要使用的主键,并且它必须包括需要索引和用作组的所有字段。两个 sql_group_column 条目将声明 Assembly 和 Model 可用于过滤结果。并且 search 实用程序将使用
sql_query_info 来查找匹配记录。在查询中,$id 被替换为 searchd 返回的每个主键。

最后一个配置步骤是构建索引。清单 8 显示了数据源 catalog 的索引。

清单 8. 描述 catalog 数据源的一个可能的索引

index catalog
{
    source                  = catalog
    path                    = /var/data/sphinx/catalog
    morphology              = stem_en

    min_word_len            = 3
    min_prefix_len          = 0
    min_infix_len           = 3
}

第 1 行将指向 sphinx.conf 文件中的指定数据源。第 2 行将定义存储索引数据的位置;按照约定,Sphinx 索引将被存储到 /var/data/sphinx 中。第 3 行将允许索引使用英文词法。并且第 5 行至第 7 行将告诉索引器只索引含有三个字符或更多字符的那些单词,并且为每个这样的字符的子字符串创建中缀索引(为了便于引用,清单 9 显示了 Body Parts 的完整示例 sphinx.conf 文件)。

清单 9. Body Parts 的示例 sphinx.conf

source catalog
{
    type                            = mysql

    sql_host                        = localhost
    sql_user                        = reaper
    sql_pass                        = s3cr3t
    sql_db                          = body_parts
    sql_sock                        =  /var/run/mysqld/mysqld.sock
    sql_port                        = 3306                  

    # indexer query
    # document_id MUST be the very first field
    # document_id MUST be positive (non-zero, non-negative)
    # document_id MUST fit into 32 bits
    # document_id MUST be unique

    sql_query                       = /
            SELECT /
                    id, partno, description, /
                    assembly, model /
            FROM /
                    Catalog;

    sql_group_column                = assembly
    sql_group_column                = model

    # document info query
    # ONLY used by search utility to display document information
    # MUST be able to fetch document info by its id, therefore
    # MUST contain ‘$id‘ macro
    #

    sql_query_info          = SELECT * FROM Inventory WHERE id=$id
}

index catalog
{
    source                  = catalog
    path                    = /var/data/sphinx/catalog
    morphology              = stem_en

    min_word_len            = 3
    min_prefix_len          = 0
    min_infix_len           = 3
}

searchd
{
	port				= 3312
	log					= /var/log/searchd/searchd.log
	query_log			= /var/log/searchd/query.log
	pid_file			= /var/log/searchd/searchd.pid
}

[连载]Java程序设计(03)---任务驱动方式:寻找高富帅和屌丝

时间: 2024-11-06 17:59:56

[连载]Java程序设计(03)---任务驱动方式:寻找高富帅和屌丝的相关文章

[连载]Java程序设计(04)---任务驱动方式:工资结算系统

任务:还是在上一家公司,该公司将职员分为三类:部门经理.技术员和销售员.在发工资的时候,部门经理拿固定月薪8000元,技术人员按每小时100元领取月薪,销售人员按照500元底薪加当月销售额的4%进行提成,设计并实现一个工资结算系统. 分析:不管是部门经理.技术员还是销售员都具有员工的共同特征,可以先设计一个员工类(Employee),并将结算工资的方法设计为抽象方法,因为不同的员工有不同的结算工资的方式,需要进行多态实现.所谓的抽象方法就是没有方法体并被abstract修饰符修饰的方法.如果一个

[连载]Java程序设计(01)---任务驱动方式:英制单位转换成公制单位

任务:你所在的公司是一家美国的服装设计和制造公司,现在这家公司打算进入欧洲市场,于是需要一个将英制单位(英寸)换算为公制单位(厘米)的程序.已知1英寸=2.54厘米,该程序输入以英寸为单位的长度,显示该长度对应的厘米数.例如:输入英寸:2.5,输出:2.5英寸=6.35厘米. package com.lovo; import java.util.Scanner; public class MyConverter { public static void main(String[] args) {

[连载]Java程序设计(02)---任务驱动方式:个人所得税计算器

上周有厂商到公司测试,拿了一块据说很猛的网络处理加速PCIe板卡,拎在手里沉甸甸的很有分量,最让人意淫的是那4个万兆光口,于是我迫不及待的想要一览光口转发时那种看不见的震撼.       可是,仅凭4个光口怎么测试?起码你要有个"对端"啊!任何人应该都不想扛着三台机器在客户们之间跑来跑去测试其转发性能,当然你也不能指望客户那里就一定有你需要的"对端"设备,比如我们公司就没有这种和万兆光口对接的设备,不过赶巧的是,那天还真有一台设备带有万兆光口,但是只是碰巧了.最佳的

[连载]Java程序设计(04)---任务驱动的方法:工资结算系统

任务:或在公司,该公司将其分为三类人员:部门经理.销售员.在发工资的时候,部门经理拿固定月薪8000元.技术人员按每小时100元领取月薪.销售人员依照500元底薪加当月销售额的4%进行提成.设计并实现一个工资结算系统. 分析:无论是部门经理.技术员还是销售员都具有员工的共同特征.能够先设计一个员工类(Employee).并将结算工资的方法设计为抽象方法,由于不同的员工有不同的结算工资的方式,须要进行多态实现.所谓的抽象方法就是没有方法体并被abstract修饰符修饰的方法.假设一个类中有抽象方法

20172319 2018.03.27-04.05 《Java程序设计》第4周学习总结

20172319 2018.03.27-04.05 <Java程序设计>第4周学习总结 教材学习内容总结 第四章 编写类 类与对象的回顾:对象是有状态的,状态由对象的属性值确定.属性由类中的声明的变量所定义.对象的操作可能改变该对象的状态.对象的操作由 类中声明的方法定义. 类的分析:类的成员(类的数据和方法):构造方法(给类赋初值):实例数据(变量声明的位置定义其作用域):UML类图(类及其对象关系可视化描述). 封装:(1) 可见性修饰符:public(公有):private(私有,只能从

20145326 《Java程序设计》第6周学习总结

20145326 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 一.使用InputStream与OutputStream 1.串流设计的概念 想活用输入/输出API,一定要先了解Java中如何以串流抽象化输入/输出概念,以及InputStream.OutputStream继承架构.如此一来,无论标准输入/输出.文档输入/输出.网络输入/输出.数据库输入/输出都可以用一致的操作来处理.Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象,其实数据就好比水,串

20145331《Java程序设计》第5周学习总结

20145331<Java程序设计>第5周学习总结 教材学习内容总结 第八章 概述 Java异常机制主要依赖于try.catch.finally.throw.throws五个关键字. 语法格式如下: try { 被检代码; } catch(异常类 变量) { 处理异常的代码(处理方式): } 关键词try后的一对大括号将一块可能发生异常的代码包起来,称为监控区域.Java方法在运行过程中出现异常,则创建异常对象.将异常抛出监控区域之 外,由Java运行时系统试图寻找匹配的catch子句以捕获异

20145326 《Java程序设计》第5周学习总结

20145326 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 一.语法与继承结构 1.使用try .catch 我们编写程序时总有些由意想不到的状况而引发的错误,java中的错误以对象方式呈现为java.lang.Throwable的各种子类实例.只要能捕捉包装错误的对象,就可以针对该错误做一些处理.java中所有错误都会被打包为对象,如果愿意,可以尝试(try)捕捉(catch)代表错误的对象后做一些处理.以书上228页的代码为例,这里使用了try,catch语法,JVM会

20145321曾子誉《Java程序设计》第一周学习总结

20145321 <Java程序设计>第1周学习总结 教材学习内容总结 第一章 1.三大平台:Java SE.Java EE .Java ME 2.Java SE:由JVM.JRE.JDK.Java语言四部分组成. JVM:操作系统,虚拟机. JRE:执行环境,包括JVM. JDK:包含JRE及开发过程中需要的一些工具程序. 3.JCP.JSR.RI.TCK的关系:任何想要提议加入Java的功能或特性,必须以JSR正式文件的方式提交,经过JCP这个国际组织投票通过,成为最终文件,由此做出的参考