• 搜索引擎分词:Nutch整合Paoding中文分词步骤详解


    搜索引擎+B2B平台+SNS网站=?, 一个三不像网站。偏偏投资人需要这样一个三不像网站。从4月份开始组建团队。时间一瞬2个月过去了。做B2B需要的就是大工作量和时间,而做搜索引擎光分词这块就搞的头大。在此结合开源数据写个一二,已备后用。

    搜索引擎需要的就是数据,抓取海量数据、然后存储、分析、建立索引、计算,最终根据用户需求快速检索出结果。存储分析和建立索引的过程开源项目中有个Hadoop是不二之选。这里分析的不是hadoop,而是搜索引擎中最后一步,也是至关重要的一步:中文分词。因为程序员基本是写java为主,故在考虑搜索引擎时,就采用了搜索领域影响颇深的基于纯java语言开发的Nutch搜索引擎。搜索引擎处理英文文档时,几乎不需要特殊的加工处理,英文文档本身就是以词为单位的组织,词个词之间是靠空格或标点符号显式地表示词的边界。我们采用的庖丁解牛正是为中文的分词提供了技术基础。首先,用wget下载了细胞词库,哇,太棒了,数据大的惊人。加上paoding自带的22M词库,基本可以满足我们词典库。

    第一步是建立两个文件,在nutch目录的src/plugin目录下建立两个文件夹分别命名为analysis-zh,lib-paoding-analyzers。然后在这两个文件夹下建立plugin.xml和build.xml。
    analysis-zh文件夹下plugin.xml内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin id="analysis-zh" name="Chinese Analysis Plug-in" version="1.0.0"
    provider-name="net.paoding.analysis">
    <runtime>
    <library name="analysis-zh.jar">
    <export name="*"/>
    </library>
    </runtime>
    <requires>
    <import plugin="nutch-extensionpoints"/>
    <import plugin="lib-paoding-analyzers"/>
    </requires>
    <extension id="org.apache.nutch.analysis.zh"
    name="Chinese Analyzer"
    point="org.apache.nutch.analysis.NutchAnalyzer">
    <implementation id="ChineseAnalyzer"
    class="org.apache.nutch.analysis.zh.ChineseAnalyzer">
    <parameter name="lang" value="zh"/>
    </implementation>
    </extension>
    </plugin>

    analysis-zh文件夹下build.xml的内容如下:
    <project name="analysis-zh" default="jar-core">
    <import file="../build-plugin.xml"/>
    <!-- Build compilation dependencies -->
    <target name="deps-jar">
    <ant target="jar" inheritall="false" dir="../lib-paoding-analyzers"/>
    </target>
    <!-- Add compilation dependencies to classpath -->
    <path id="plugin.deps">
    <fileset dir="${nutch.root}/build">
    <include name="**/lib-paoding-analyzers
    package org.apache.nutch.analysis.zh;
    // JDK imports
    import java.io.Reader;
    // Lucene imports
    import net.paoding.analysis.analyzer.PaodingAnalyzer;

    import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.analysis.TokenStream;
    // Nutch imports
    import org.apache.nutch.analysis.NutchAnalyzer;

    public class ChineseAnalyzer extends NutchAnalyzer {
    private final static Analyzer ANALYZER = new PaodingAnalyzer();

    public ChineseAnalyzer() { }

    public TokenStream tokenStream(String fieldName, Reader reader)
    {
    return ANALYZER.tokenStream(fieldName, reader);
    }
    }
    lib-paoding-analyzers文件夹下plugin.xml的内容如下:
    <plugin
    id="lib-paoding-analyzers"
    name="paoding Analysers"
    version="2.4.0"
    provider-name="net.paoding">

    <runtime>
    <library name="lib-paoding-analyzers.jar">
    <export name="*"/>
    </library>
    </runtime>

    </plugin>
    lib-paoding-analyzers文件夹下build.xml内容如下:
    <?xml version="1.0"?>
    <project name="lib-paoding-analyzers" default="jar">

    <import file="../build-plugin.xml"/>

    <!--
    ! Override the compile and jar targets,
    ! since there is nothing to compile here.
    ! -->
    <target name="compile" depends="init"/>

    <target name="jar" depends="compile">
    <copy todir="${build.dir}" verbose="true">
    <fileset dir="./lib" includes="**
    analyzer=PAODING_ANALYZER;
    return analyzer.tokenStream(fieldName, reader);
    }

    修改NutchAnalysis.jj,把130行的| <SIGRAM: <CJK> >修改成| <SIGRAM: (<CJK>)+ >
    修改org.apache.nutch.indexer.lucene.LuceneWriter
    把public void write(NutchDocument doc) throws IOException {
    final Document luceneDoc = createLuceneDoc(doc);
    ........
    }
    改成public void write(NutchDocument doc) throws IOException {
    final Document luceneDoc = createLuceneDoc(doc);
    String lang = null;
    if(luceneDoc.get("lang") == null) {
    lang = "zh";
    }
    final NutchAnalyzer analyzer = analyzerFactory.get(lang);
    if (Indexer.LOG.isDebugEnabled()) {
    Indexer.LOG.debug("Indexing [" + luceneDoc.get("url")
    + "] with analyzer " + analyzer + " (" + luceneDoc.get("lang")
    + ")");
    }
    writer.addDocument(luceneDoc, analyzer);

    }
    修改org.apache.nutch.analysis.NutchAnalysis,加上方法:
    final public Query parseByLucene(Configuration conf) throws ParseException {

    Query query = new Query(conf);

    if (queryString.length() > 0) {
    // lucene分词
    org.apache.lucene.queryParser.QueryParser parserLucene =
    new org.apache.lucene.queryParser.QueryParser("", analyzer);
    org.apache.lucene.search.Query q = null;
    try {
    q = parserLucene.parse(queryString);
    } catch (org.apache.lucene.queryParser.ParseException e) {
    e.printStackTrace();
    }

    String termStrings = q.toString();
    if (termStrings.indexOf(" ") > -1)
    termStrings = termStrings.substring(1, termStrings.length()-1);
    String[] terms = termStrings.split(" ");

    for (int i = 0; i < terms.length; i++) {
    String[] tems = {terms[i]};
    query.addRequiredPhrase(tems, Clause.DEFAULT_FIELD);
    }
    }

    return query;
    }
    然后修改这个类的方法blic static Query parseQuery(){}里面的return parser.parse(conf); 修改为return parser.parseByLucene(conf);

    第四步,修改Nutch的build.xml文件
    修改根目录的build.xml,在target war的<lib> </lib>里加上
    <include name="paoding-analysis.jar"/>
    修改150行处的<target name="job" depends="compile">,改为<target name="job" depends="compile,war"> 这样编译后能自动在bulid文件夹下生成nutch -1.0.job,nutch-1.0.war,nutch-1.0.jar文件了。
    修改nutch-1.0\src\plugin下的build.xml文件,加上
    <target name="deploy">
    <ant dir="analysis-zh" target="deploy"/>
    <ant dir="lib-paoding-analyzers" target="deploy"/>
    .......
    </target>

    <target name="clean">
    <ant dir="analysis-zh" target="clean"/>
    <ant dir="lib-paoding-analyzers" target="clean"/>
    .......
    </target>

    最后就可以用 ant进行编译了,编译后的结果测试:http://www.huisou.com
    编译后把\nutch-1.0\build下出现的analysis-zh和lib-paoding-analyzers两文件夹复制到\nutch-1.0\plugins下面,删掉里面的classes和test文件。并把\nutch-1.0\src\plugin下相同文件夹下的plugin.xml复制过去。在用ant编译一次。把\nutch-1.0\build下的nutch -1.0.job,nutch-1.0.war,nutch-1.0.jar复制到nutch的根目录下替代原来的文件。

    用Nutch抓取来的1T数据,通过hadoop的MapReduce进行存储实现,然后建立倒索引,配置Tomcat,就可以体验分词带来的搜索效果了。

    山寨级别的搜索引擎自然不能与Google、百度相提并论。在搜索引擎实现的每一个步骤(数据抓取、存储、索引、分词系统、分布式查询等)每一个都是巨大的课题,值得我们去深入研究。同时欢迎更多的搜索引擎互联网爱好者加入我们的团队,一起学习进步。

  • 相关阅读:
    redis 配置文件说明
    Python 详解命令行解析
    Python 的字符编码
    pt-online-schema-change utf8mb4 错误解决方法【转】
    [MySQL 5.6] Innodb新特性之export/import 表文件
    查找数据库大小和表大小
    MySQL 增删列
    使用MySQL Shell创建MGR
    Qingcloud_MySQL Plus(Xenon) 高可用搭建实验
    MySQL事务提交流程
  • 原文地址:https://www.cnblogs.com/shlcn/p/2112889.html
Copyright © 2020-2023  润新知