`
twh1224
  • 浏览: 95587 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Lucene学习(9)

阅读更多
Lucene的StandardAnalyzer分析器。

不同的Lucene分析器Analyzer,它对TokenStream进行分词的方法是不同的,这需要根据具体的语言来选择。比如英文,一般是通过空格来分割词条,而中文汉字则不能通过这种方式,最简单的方式就是单个汉字作为一个词条。

TokenStream是通过从设备或者其他地方获取数据源而构造的一个流,我们要执行分词的动作,应该对这个TokenStream进行操作。

TokenStream也可以不是直接通过数据源构造的流,可以是经过分词操作之后读入TokenFilter的一个分词流。

从本地磁盘的文件读取文本内容,假定在文本文件shirdrn.txt中有下列文字:

中秋之夜,享受着月华的孤独,享受着爆炸式的思维跃迁。

通过使用FileReader构造一个流,对其进行分词:

package org.shirdrn.lucene; 
 
import java.io.File; 
import java.io.FileReader; 
import java.io.Reader; 
 
import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.Token; 
import org.apache.lucene.analysis.TokenStream; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
 
public class MyAnalyzer { 
 
public static void main(String[] args) { 
   try { 
    File file = new File("E:\\shirdrn.txt"); 
    Reader reader = new FileReader(file); 
   Analyzer a = new StandardAnalyzer(); 
    //Analyzer a = new CJKAnalyzer(); 
    //Analyzer a = new ChineseAnalyzer(); 
    //Analyzer a = new WhitespaceAnalyzer(); 
    TokenStream ts = a.tokenStream("", reader); 
    Token t = null; 
    int n = 0; 
    while((t = ts.next()) != null ){ 
     n ++ ; 
     System.out.println("词条"+n+"的内容为 :"+t.termText()); 
    } 
    System.out.println("== 共有词条 "+n+" 条 =="); 
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
} 
} 


这里使用StandardAnalyzer分析器,而且使用了不带参数的构造器StandardAnalyzer(),在StandardAnalyzer类的这个不带参数的构造器中,指定了一个过滤字符数组STOP_WORDS:

public StandardAnalyzer() { 
    this(STOP_WORDS); 
} 


而在StandardAnalyzer类中定义的STOP_WORDS 数组实际是引用StopAnalyzer类的ENGLISH_STOP_WORDS数组,该数组中可以根据需要添加过滤的字符:

public static final String[] STOP_WORDS = StopAnalyzer.ENGLISH_STOP_WORDS; 


StopAnalyzer类中ENGLISH_STOP_WORDS数组原始内容如下所示:

public static final String[] ENGLISH_STOP_WORDS = { 
    "a", "an", "and", "are", "as", "at", "be", "but", "by", 
    "for", "if", "in", "into", "is", "it", 
    "no", "not", "of", "on", "or", "such", 
    "that", "the", "their", "then", "there", "these", 
    "they", "this", "to", "was", "will", "with" 
}; 


都是一些英文单词,而且这些单词对于检索关键字意义不大,所以在分析的时候应该把出现的这些单词过滤掉。

如果按照默认的STOP_WORDS运行上面我们的测试程序,则根本没有对中文起到过滤作用,测试结果如下所示:

词条1的内容为 :中
词条2的内容为 :秋
词条3的内容为 :之
词条4的内容为 :夜
词条5的内容为 :享
词条6的内容为 :受
词条7的内容为 :着
词条8的内容为 :月
词条9的内容为 :华
词条10的内容为 :的
词条11的内容为 :孤
词条12的内容为 :独
词条13的内容为 :享
词条14的内容为 :受
词条15的内容为 :着
词条16的内容为 :爆
词条17的内容为 :炸
词条18的内容为 :式
词条19的内容为 :的
词条20的内容为 :思
词条21的内容为 :维
词条22的内容为 :跃
词条23的内容为 :迁
== 共有词条 23 条 ==

我们可以在org.apache.lucene.analysis.StopAnalyzer类中定制自己的STOP_WORDS,例如我们定义:

public static final String[] ENGLISH_STOP_WORDS = { 
     "着", "的", "之", "式" 
};


则再执行上面的测试程序,分词过程中会过滤掉出现在ENGLISH_STOP_WORDS数组中的词条,如下所示:

词条1的内容为 :中
词条2的内容为 :秋
词条3的内容为 :夜
词条4的内容为 :享
词条5的内容为 :受
词条6的内容为 :月
词条7的内容为 :华
词条8的内容为 :孤
词条9的内容为 :独
词条10的内容为 :享
词条11的内容为 :受
词条12的内容为 :爆
词条13的内容为 :炸
词条14的内容为 :思
词条15的内容为 :维
词条16的内容为 :跃
词条17的内容为 :迁
== 共有词条 17 条 ==

另外,因为StandardAnalyzer类具有很多带参数的构造函数,可以在实例化一个StandardAnalyzer的时候,通过构造函数定制分析器,例如使用:

public StandardAnalyzer(Set stopWords) 


构造的分析器如下:

    Set stopWords = new HashSet(); 
    stopWords.add("着"); 
    stopWords.add("的"); 
    stopWords.add("之"); 
    stopWords.add("式"); 
    Analyzer a = new StandardAnalyzer(stopWords); 


运行结果同修改StopAnalyzer类中的STOP_WORDS结果是一样的。

还有一个构造函数,通过使用数组指定stopWords的过滤词条:

public StandardAnalyzer(String[] stopWords) { 
    stopSet = StopFilter.makeStopSet(stopWords); 
} 


调用了StopFilter类的makeStopSet方法对stopWords中的字符进行了转换处理:

public static final Set makeStopSet(String[] stopWords) { 
    return makeStopSet(stopWords, false); 
} 


又调用了该类的一个重载的方法makeStopSet,第一个参数指定过滤词条的数组,第一个参数为boolean类型,设置是否要将大写字符转换为小写:

public static final Set makeStopSet(String[] stopWords, boolean ignoreCase) { 
    HashSet stopTable = new HashSet(stopWords.length); 
    for (int i = 0; i < stopWords.length; i++) 
      stopTable.add(ignoreCase ? stopWords[i].toLowerCase() : stopWords[i]); 
    return stopTable; 
} 


在StandardAnalyzer类中,没有把stopWords中的词条转换为小写。

上面的三种构造StandardAnalyzer分析器的方式都是在程序中指定要过滤词条,程序的独立性比较差,因为每次想要添加过滤词条都需要改动程序。

StandardAnalyzer还提供了两种从数据源读取过滤词条的文本的构造方式:

public StandardAnalyzer(File stopwords) throws IOException { 
    stopSet = WordlistLoader.getWordSet(stopwords); 
} 
 
public StandardAnalyzer(Reader stopwords) throws IOException { 
    stopSet = WordlistLoader.getWordSet(stopwords); 
} 


他们分别使用File和Reader分别来构造一个File对象和读取字符流,从指定的数据源读取内容,然后调用WordlistLoader类的getWordSet静态方法来对读取的字符流进行转换操作,以从File对象中获取字符为例:

public static HashSet getWordSet(File wordfile) throws IOException { 
    HashSet result = new HashSet(); 
    FileReader reader = null; 
    try { 
      reader = new FileReader(wordfile); 
      result = getWordSet(reader); 
    } 
    finally { 
      if (reader != null) 
        reader.close(); 
    } 
    return result; 
} 


实际上仍然通过File对象构造一个FileReader读取字符流,然后从流中取得过滤的词条,加入到HashSet 中。这里调用了获取HashSet的getWordSet方法,在方法getWordSet中才真正地实现了提取词条的操作:

public static HashSet getWordSet(Reader reader) throws IOException { 
    HashSet result = new HashSet(); 
    BufferedReader br = null; 
    try { 
      if (reader instanceof BufferedReader) { 
        br = (BufferedReader) reader; 
      } else { 
        br = new BufferedReader(reader); 
      } 
      String word = null; 
      while ((word = br.readLine()) != null) { 
        result.add(word.trim()); 
      } 
    } 
    finally { 
      if (br != null) 
        br.close(); 
    } 
    return result; 
} 


实际上仍然通过File对象构造一个FileReader读取字符流,然后从流中取得过滤的词条,加入到HashSet 中。这里调用了获取HashSet的getWordSet方法,在方法getWordSet中才真正地实现了提取词条的操作:

public static HashSet getWordSet(Reader reader) throws IOException { 
    HashSet result = new HashSet(); 
    BufferedReader br = null; 
    try { 
      if (reader instanceof BufferedReader) { 
        br = (BufferedReader) reader; 
      } else { 
        br = new BufferedReader(reader); 
      } 
      String word = null; 
      while ((word = br.readLine()) != null) { 
        result.add(word.trim()); 
      } 
    } 
    finally { 
      if (br != null) 
        br.close(); 
    } 
    return result; 
} 


这里提取词条要求读入的文本是按照行来分割过滤词条的,即每行作为一个词条。对于中文,只能是每个字作为一行,如果以两个的词语作为一行,处理后根本没有加入到过滤词条的HashSet中,这时因为StandardAnalyzer分析器是以单个中文汉字作为一个词条的。我们可以定制自己的分析器。

测试一下上述说明的情况。

在本地磁盘上建立一个txt文本stopWords.txt,添加过滤词条:






测试程序如下所示:

 public static void main(String[] args) { 
   try { 
    File file = new File("E:\\shirdrn.txt"); 
    FileReader stopWords = new FileReader("E:\\stopWords.txt"); 
    Reader reader = new FileReader(file);    
    Analyzer a = new StandardAnalyzer(stopWords); 
    TokenStream ts = a.tokenStream("", reader); 
    Token t = null; 
    int n = 0; 
    while((t = ts.next()) != null ){ 
     n ++ ; 
     System.out.println("词条"+n+"的内容为 :"+t.termText()); 
    } 
    System.out.println("== 共有词条 "+n+" 条 =="); 
    
   } catch (Exception e) { 
    e.printStackTrace(); 
   } 
} 


测试输出结果同前面的一样,都对词条进行了过滤:

词条1的内容为 :中
词条2的内容为 :秋
词条3的内容为 :夜
词条4的内容为 :享
词条5的内容为 :受
词条6的内容为 :月
词条7的内容为 :华
词条8的内容为 :孤
词条9的内容为 :独
词条10的内容为 :享
词条11的内容为 :受
词条12的内容为 :爆
词条13的内容为 :炸
词条14的内容为 :思
词条15的内容为 :维
词条16的内容为 :跃
词条17的内容为 :迁
== 共有词条 17 条 ==
分享到:
评论

相关推荐

    lucene学习资料收集

    【标题】:“Lucene学习资料收集” 【描述】:Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发。这个资料集可能包含了关于如何理解和使用Lucene的各种资源,特别是通过博主huanglz19871030在iteye上的...

    Lucene的的学习资料及案例

    **Lucene学习指南** Lucene是一个高性能、全文检索库,由Apache软件基金会开发并维护,是Java编程语言中广泛使用的搜索引擎库。它提供了一个简单的API,使得开发者能够方便地在应用中实现全文检索功能。本篇文章将...

    lucene学习pdf2

    "lucene学习pdf2" 提供的文档,无疑是对Lucene深入理解的一把钥匙,它涵盖了Lucene的核心概念、操作流程以及高级特性。 首先,Lucene的基础知识是必不可少的。Lucene的核心在于索引和搜索,它将非结构化的文本数据...

    lucene学习

    Lucene的基础知识 1、案例分析:什么是全文检索,如何实现全文检索 2、Lucene实现全文检索的流程 a) 创建索引 b) 查询索引 3、配置开发环境 4、创建索引库 5、查询索引库 6、分析器的分析过程 a) 测试分析器的分词...

    Lucene学习源码.rar

    本文将主要围绕Java Lucene进行深入探讨,并基于提供的“Lucene学习源码.rar”文件中的“Lucene视频教程_讲解部分源码”展开讨论。 一、Lucene核心概念 1. 文档(Document):Lucene中的基本单位,用于存储待检索...

    lucene学习资料

    《Lucene学习资料》 Lucene是一个开源的全文搜索引擎库,由Apache软件基金会维护。它提供了高级的文本分析和索引功能,使得开发者能够轻松地在应用程序中集成强大的搜索功能。这个资料包中的《Lucene in Action_2nd...

    Lucene-2.0学习文档

    本篇文章将围绕"Lucene-2.0学习文档"的主题,结合Indexer.java、MyScoreDocComparator.java和MySortComparatorSource.java这三个关键文件,深入探讨Lucene的核心概念和实际应用。 首先,我们来看`Indexer.java`。这...

    Lucene3.3.0学习Demo

    **Lucene 3.3.0 学习Demo** Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发。在3.3.0版本中,Lucene提供了强大的文本搜索功能,包括分词、索引创建、查询解析和结果排序等。这个"Lucene3.3.0学习Demo...

    lucene学习-02

    【标题】:“Lucene学习-02” 在深入探讨“Lucene学习-02”这一主题之前,我们先来理解一下Lucene的核心概念。Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,广泛应用于各种搜索引擎和信息检索系统。...

    Lucene.net学习帮助文档

    **Lucene.net学习帮助文档** Lucene.net是一个开源全文搜索引擎库,它是Apache Lucene项目的一部分,专门针对.NET Framework进行了优化。这个压缩包包含了Lucene.net的源码和中文学习文档,旨在帮助开发者深入理解...

    Lucene 3.6 学习笔记

    【Lucene 3.6 学习笔记】 Lucene 是一个高性能、全文本搜索库,广泛应用于各种搜索引擎的开发。本文将深入探讨Lucene 3.6版本中的关键概念、功能以及实现方法。 ### 第一章 Lucene 基础 #### 1.1 索引部分的核心...

    【大搜集:lucene学习资料】---<下载不扣分,回帖加1分,欢迎下载,童叟无欺>

    lucene学习笔记 1 .txt lucene学习笔记 2.txt lucene学习笔记 3 .txt lucene入门实战.txt Lucene 的学习 .txt Lucene-2.0学习文档 .txt Lucene入门与使用 .txt lucene性能.txt 大富翁全文索引和查询的例子...

    搜索引擎lucene学习资料

    通过这些学习资料,读者可以系统地学习搜索引擎的理论基础,掌握Lucene的核心功能,同时也能了解到如何在实际项目中应用这些技术,提升搜索系统的性能和用户体验。这些知识对于从事信息检索、网站开发、大数据分析等...

    Lucene学习工具包.zip

    **Lucene学习工具包** Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。这个"Lucene学习工具包.zip"包含了学习Lucene所需的重要资料和资源,旨在帮助开发者深入理解和掌握Lucene的核心概念、功能...

    lucene4.8学习资料和案例

    《Lucene 4.8学习指南与实战案例分析》 Lucene是一个强大的全文搜索引擎库,由Apache软件基金会开发,主要用于Java环境。版本4.8在功能和性能上都有显著提升,是许多开发者进行文本检索应用开发的重要工具。本文将...

    lucene学习总结

    **Lucene学习总结** 在深入理解Lucene之前,我们首先需要了解什么是全文检索。全文检索是一种从大量文本数据中快速查找所需信息的技术。它通过建立索引来实现高效的搜索,而Lucene正是Java环境下最著名的全文搜索...

Global site tag (gtag.js) - Google Analytics