• 使用Apache Solr实现企业搜索


    基于 Lucene 搜索引擎并且在 Apache Software License 许可下以开源形式提供,Solr 是(根据 Lucene 站点)“基于 Lucene Java™ 搜索库、配有 XML/HTTP 和 JSON API、命中结果突出显示、分面组配式搜索、缓存、复制和 Web 管理界面的开源企业搜索服务器”。

    其中值得注意的是,大流量的 Web 站点、Netflix、Digg 和 CNET 的 News.com 和 CNET Reviews 使用 Solr 来增强搜索功能。由 Solr 驱动的公共站点的长串列表可以在 Solr 维基中找到(请参阅 参考资料)。

    了解如何使用 Solr 和 PHP 创建搜索汽车零部件数据库的小型应用程序。虽然示例数据库只是包含一些记录,但是它轻轻松松就能包含数百万条记录。本文中使用的所有源代码均可从 下载 部分获得。

    安装 Solr

    要将 Solr 与 PHP 结合使用,您必须安装 Solr,设计索引,准备 Solr 要索引的数据,载入索引,编写执行查询的 PHP 代码和显示结果。创建可搜索索引所需的大部分工作可以通过命令行执行。当然,Solr 的 PHP 编程接口也会影响索引的内容。

    Solr 是用 Java 技术实现的。要运行 Solr 及其管理工具,您必须安装 Java V1.5 软件开发包 (Java 5 SDK)。几个提供商都提供了 Java V1.5 SDK —— 例如,Sun MicrosystemsIBM® BEA Systems —— 并且每个实现都能够驱动 Solr。只需选择适用于您的操作系统的 Java 包并遵循相应的说明来完成安装。

    在 许多情况下,安装 Java V1.5 就像运行自提取归档和接受许可证协议条款一样简单。归档中的脚本在几秒钟内就能完成所有大部分艰巨任务。其他操作系统(例如 Debian)将在 APT 系统库中提供 Java 5 SDK。例如,如果使用 Debian 或 Ubuntu,则可以用 sudo apt-get install sun-java5-jdk 安装 Java V1.5 软件。

    APT 还将自动下载使用 Java 5 SDK 所需的所有依赖性,非常方便。

    如果 Java 软件已经安装并且 Java 可执行文件已在 PATH 中,请运行 java -version 来确定拥有的 Java 代码。

    在 这里,让我们使用 Mac OS X V10.5 Leopard 操作系统作为演示的基础。Apple 的 Leopard 附带了 Java V1.5。只要对 Apache 的默认配置进行微小更改,Leopard 也可以运行 PHP 应用程序。在 Leopard 终端窗口中运行 java -version 将生成以下输出。


    清单 1. 在 Leopard 终端窗口中运行 java -version
                    
    $ which java
    /usr/bin/java

    $ java -version
    java version "1.5.0_13"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
    Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)

    :Leopard 将允许您在 /Applications/Utilities/Java 的 Java Preferences 应用程序中的 Java V1.4 与 V1.5 之间来回切换。如果 Leopard 安装显示 V1.4,则打开 Java Preferences 并按照图 1 所示更改设置。


    图 1. Leopard 中的 Java Preferences 应用程序
    Leopard 中的 Java Preferences 应用程序

    要安装 Solr,请访问 Apache.org,单击 Resources > Download,选择一个方便访问的项目镜像,并且在所示文件夹内浏览选择 Solr V1.2 的 tarball(.tgz 文件)。下载将传输名称类似 apache-solr-1.2.0.tgz 的文件。用下列代码解压缩 tarball。


    清单 2. 解压缩 tarball
                    
    $ tar xzf apache-solr-1.2.0.tgz

    $ ls -F apache-solr-1.2.0
    CHANGES.txt NOTICE.txt dist/ lib/
    KEYS.txt README.txt docs/ src/
    LICENSE.txt build.xml example/

    在新创建的目录中,名为 dist 的文件夹包含绑定为 Java 归档 (JAR) 的 Solr 代码。子目录 example/exampledocs 包含已经格式化的数据示例 —— 通常为 XML 代码 —— 并且准备好供 Solr 索引。

    example 目录包含一个完整的样例 Solr 应用程序。要运行它,只需用应用程序归档 start.jar 启动 Java 引擎。


    清单 3. 启动 Java 引擎
                    
    $ java -jar start.jar
    2007-11-10 15:00:16.672::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
    2007-11-10 15:00:16.866::INFO: jetty-6.1.3
    ...
    INFO: SolrUpdateServlet.init() done
    2007-11-10 15:00:18.694::INFO: Started SocketConnector @ 0.0.0.0:8983

    应用程序现在可以在 8983 端口上使用。启动浏览器并在地址栏中键入 http://localhost:8983/solr/admin/。这是用于管理 Solr 的接口(要停止 Solr 服务器,请在命令行中键入 Ctrl+C 组合键)。

    但是 Solr 索引中还没有数据可供管理或查询。





    回页首


    把数据装入 Solr

    Solr 非常灵活,支持创建有效索引的各种数据类型和规则。而且虽然 Solr 支持数据类型和规则十分广泛,但是如果标准组件不够用,还可以通过编写新的 Java 类进一步自定义 Solr。

    给定一组数据类型和规则,您就可以创建一个 Solr 模式来描述数据和控制应当怎样构造索引。然后导出数据来匹配模式并将数据装入 Solr。Solr 将动态创建索引,在记录被创建、修改或删除时立即更新每个索引。

    可以在 Apache.org 的 Solr 源代码库中找到默认的 Solr 模式。为供参考,下面显示了默认模式的代码片段。


    清单 3. 默认的 Solr 模式代码片段
                    
    <schema name="example" version="1.1">
    ...
    <fields>
    <field name="id" type="string" indexed="true" stored="true" required="true" />
    <field name="name" type="text" indexed="true" stored="true"/>
    <field name="nameSort" type="string" indexed="true" stored="false"/>
    <field name="cat" type="text" indexed="true" stored="true" multiValued="true"/>
    ...
    </fields>

    <uniqueKey>id</uniqueKey>
    ...
    <copyField source="name" dest="nameSort"/>
    ...
    </schema>

    模式的大部分内容都无需加以说明,但是有一些方面需要注意:

    • 如示,字段 id 是字符串 (type="string") 并且应当被索引 (indexed="true")。它也是一个必需字段 (required="true")。使用此模式,载入 Solr 的每条记录必须为这个字段提供值。<uniqueKey>id</uniqueKey> 修饰词进一步说明 id 字段必须惟一(Solr 不要求 ID 字段惟一;这只是在默认索引模式中建立的规则)。属性 stored="true" 表示 id 字段应当可检索。

      为什么不把 stored 设为 false?您可以使用不可检索的字段来以不同方式给结果排序,比方说使用 nameSort,它是 name 字段的副本(最后一行中的 copyField 命令),但是行为不同。注意,nameSortstring,而 nametext。默认索引模式将采取稍微不同的方式来处理这两种类型。

    • 字段 catmultiValued。记录可以为此字段定义多个值。例如,如果应用程序管理内容,则可以给一篇文章指定多个标题。您可以使用 cat 字段(或者自定义类似字段)来捕捉所有标题。

    清单 4 显示了 example/exampledocs/ipod_other.xml 文件,该文件表示 iPod 附件分类中的两个条目。


    清单 4. 为默认 Solr 索引模式格式化的数据
                    
    <add>
    <doc>
    <field name="id">F8V7067-APL-KIT</field>
    <field name="name">Belkin Mobile Power Cord for iPod w/ Dock</field>
    <field name="manu">Belkin</field>
    <field name="cat">electronics</field>
    <field name="cat">connector</field>
    <field name="features">car power adapter, white</field>
    <field name="weight">4</field>
    <field name="price">19.95</field>
    <field name="popularity">1</field>
    <field name="inStock">false</field>
    </doc>

    <doc>
    <field name="id">IW-02</field>
    <field name="name">iPod & iPod Mini USB 2.0 Cable</field>
    <field name="manu">Belkin</field>
    <field name="cat">electronics</field>
    <field name="cat">connector</field>
    <field name="features">car power adapter for iPod, white</field>
    <field name="weight">2</field>
    <field name="price">11.50</field>
    <field name="popularity">1</field>
    <field name="inStock">false</field>
    </doc>
    </add>

    add 元素是用于将封装记录添加到索引中的 Solr 命令。每条记录都将被捕捉到 doc 元素中,该元素将使用一组名为 field 的元素来指定字段值。字段 weightpriceinStockmanufeaturespopularity 都是在默认 Solr 索引模式中定义的其他字段。features 字段拥有与 cat 相同的属性,但是语义不同:它列举了产品的功能,数量可能较多。





    回页首


    搜索汽车零部件

    本例将索引汽车零部件集。每个汽车零部件都有多个字段,表 1 中显示了最重要的字段样例。第一列中列出了字段名。第二列将提供简要描述,而第三列将列出逻辑类型。第四列将显示用于表示数据的索引类型(按照 清单 5 的模式中的定义)。


    表 1. 汽车零部件记录的字段
    名称 描述 类型 Solr 类型
    部件号(惟一,强制) 标识号 字符串 partno
    名称 简要描述 字符串 name
    型号(必需,多值) 型号,例如 “Camaro” 字符串 model
    型号年份(多值) 型号年份,例如 2001 字符串 year
    价格 单价 浮点 price
    库存 是否有存货 布尔 inStock
    功能 零部件的功能 字符串 features
    时间标记 活动记录 字符串 timestamp
    重量 装运重量 浮点 weight

    清单 3 显示了汽车零部件索引所使用的 Solr 模式部分。它大部分都是基于默认 Solr 模式。使用的具体字段 —— 名称和属性 —— 只是替换了在默认模式中找到的 fields 元素(如 清单 1 中所示)。


    清单 5. 汽车零部件索引模式
                    
    <?xml version="1.0" encoding="utf-8" ?>
    <schema name="autoparts" version="1.0">
    ...
    <fields>
    <field name="partno" type="string" indexed="true"
    stored="true" required="true" />

    <field name="name" type="text" indexed="true"
    stored="true" required="true" />

    <field name="model" type="text_ws" indexed="true" stored="true"
    multiValued="true" required="true" />

    <field name="year" type="text_ws" indexed="true" stored="true"
    multiValued="true" omitNorms="true" />

    <field name="price" type="sfloat" indexed="true"
    stored="true" required="true" />

    <field name="inStock" type="boolean" indexed="true"
    stored="true" default="false" />

    <field name="features" type="text" indexed="true"
    stored="true" multiValued="true" />

    <field name="timestamp" type="date" indexed="true"
    stored="true" default="NOW" multiValued="false" />

    <field name="weight" type="sfloat" indexed="true" stored="true" />
    </fields>

    <uniqueKey>partno</uniqueKey>

    <defaultSearchField>name</defaultSearchField>
    </schema>

    针对以上字段,需要将汽车零部件数据库导出并格式化以上传到 Solr 中,如清单 6 所示。


    清单 6. 为进行索引而格式化的汽车零部件数据库
                    
    <add>
    <doc>
    <field name="partno">1</field>
    <field name="name">Spark plug</field>
    <field name="model">Boxster</field>
    <field name="model">924</field>
    <field name="year">1999</field>
    <field name="year">2000</field>
    <field name="price">25.00</field>
    <field name="inStock">true</field>
    </doc>
    <doc>
    <field name="partno">2</field>
    <field name="name">Windshield</field>
    <field name="model">911</field>
    <field name="year">1991</field>
    <field name="year">1999</field>
    <field name="price">15.00</field>
    <field name="inStock">false</field>
    </doc>
    </add>

    让我们安装新索引模式并把数据装入 Solr。首先,通过使用 Ctrl+C 组合键来停止 Solr 守护进程(如果它仍在运行)。在 example/solr/conf/schema.xml 中制作现有 Solr 模式的归档。接下来,通过清单 6 创建一个文本文件,将其保存到 /tmp/schema.xml 中,然后复制到 example/solr/conf/schema.xml 中。为清单 7 中所示的数据创建另一个文件。现在,您可以重新启动 Solr 并使用示例所提供的 posting 实用程序。


    清单 7. 启用带有新模式的 Solr
                    
    $ cd apache-solr-1.2/example
    $ cp solr/conf/schema.xml solr/conf/default_schema.xml
    $ chmod a-w solr/conf/default_schema.xml

    $ vi /tmp/schema.xml
    ...
    $ cp /tmp/schema.xml solr/conf/schema.xml

    $ vi /tmp/parts.xml
    ...

    $ java -jar start.jar
    ...
    2007-11-11 16:56:48.279::INFO: Started SocketConnector @ 0.0.0.0:8983

    $ java -jar exampledocs/post.jar /tmp/parts.xml
    SimplePostTool: version 1.2
    SimplePostTool: WARNING: Make sure your XML documents are encoded in UTF-8,
    other encodings are not currently supported
    SimplePostTool: POSTing files to http://localhost:8983/solr/update...
    SimplePostTool: POSTing file parts.xml
    SimplePostTool: COMMITting Solr index changes...

    成功!如果需要检验索引是否存在并包含两个文档,请将浏览器再次指向 http://localhost:8983/solr/admin/。您应当会在页面顶部看到 “(autoparts)”。如果看到了,请单击页面中间的查询框并键入 partno: 1 or partno: 2

    结果应当类似下面的内容:

    3 on 10 0 partno: 1 OR partno: 2 2.2
    true Boxster 924 Spark plug 1 25.0 2007-11-11T21:58:45.899Z 1999 2000
    false 911 Windshield 2 15.0 2007-11-11T21:58:45.953Z 1991 1999

    尝试其他一些查询。Lucene 维基中介绍了 Lucene 查询(Solr 中的搜索引擎)的语法(请参阅 参考资料)。

    您还应当尝试再次编辑和载入数据。由于声明了 partno 字段惟一,因此重复上传同一个部件号将只用新记录替换旧索引记录。除了 add 命令之外,您还可以使用 commitoptimizedelete。最后一个命令可以按照 ID 删除一条特定记录,也可以通过查询删除多条记录。

     
  • 相关阅读:
    数据库----索引与补充
    数据库----知识点总结
    数据库----mysql 存储引擎,表介绍
    数据库----mysql表的约束和查询
    数据库----mysql 表的操作
    初识数据库
    并发编程----协程
    并发编程----同步,异步,阻塞,非阻塞,异步加回调机制,线程队列,event事件
    并发编程----GIL,进程池/线程池
    django中的模板渲染、模板继承、组件、插件
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470521.html
Copyright © 2020-2023  润新知