lucene分词:Lucene.Net 2.3.1开发介绍 2、分词( 4)

  2.1.2可以使用内置分词

  简单分词方式并不能满足需求前文说过Lucene.Net内置分词中StandardAnalyzer分词还算比较实用(见1.1.2小节)StandardAnalyzer为什么能满足我们部分需求而它又有哪些不足呢?看分词好坏还是要从效果说起简单在中英文混合情况下StandardAnalyzer会把英文按空格拆而中文则按单字拆中文是按单字拆所以对分词准确性起到了干扰搜索结果就会不准确至少理论上是这样但是实际上StandardAnalyzer分词器并没有我们想那么差劲搜索不光和分词有关还和查询逻辑有关这个会在第 4章讲搜索时候讲作为其中个重要要素可以说是基础分词器当然还是扮演了很关键角色查询逻辑是以分词为基础分词是原石而查询逻辑则能对它雕琢

  事实上如果没有用过StandardAnalyzer分词器没有用它来解决些问题并且找到有哪些地方不足那并不能弄清楚你要什么样分词器比如现在有些内容用StandardAnalyzer作为分词器已经建立好了索引接下来进行查询操作

  代码 2.1.2.1

  Code

1using ;
2using Lucene.Net.Analysis;
3using Lucene.Net.Analysis.Standard;
4using Lucene.Net.Documents;
5using Lucene.Net.Index;
6using Lucene.Net.QueryParsers;
7using Lucene.Net.Search;
8using NUnit.Framework;
9using .Collections.Generic;
10
11 Test
12{
13  [TestFixture]
14  public StandardAnalyzerCaseTest
15  {
16    /**//// <summary>
17    /// 执行测试入口
18    /// </summary>
19    [Test]
20    public void SearcherTest
21    {
22      Index;
23      List<> list = List<> { "中华", "中国", "人民", "中国人民", "人民" };
24      for ( i = 0; i < list.Count; i)
25      {
26        Console.WriteLine("搜索词:" + list[i]);
27        Console.WriteLine("结果:");
28        Searcher(list[i]);
29        Console.WriteLine("-----------------------------------");
30      }
31    }
32
33    /**//// <summary>
34    /// 搜索
35    /// </summary>
36    /// <param name="query">搜索输入</param>
37    private void Searcher( query)
38    {
39      Analyzer analyzer = StandardAnalyzer;
40      IndexSearcher searcher = IndexSearcher("IndexDirectory");
41      QueryParser parser = QueryParser("content", analyzer);
42      Query query = parser.Parse(query);
43      Hits hits = searcher.Search(query);
44      for ( i = 0; i < hits.Length; i)
45      {
46        Console.WriteLine(hits.Doc(i).Get("content"));
47      }
48    }
49
50    /**//// <summary>
51    /// 索引数据
52    /// </summary>
53    private void Index
54    {
55      Analyzer analyzer = StandardAnalyzer;
56      IndexWriter writer = IndexWriter("IndexDirectory", analyzer, true);
57      AddDocument(writer, "中华人民共和国");
58      AddDocument(writer, "中国人民解放军");
59      AddDocument(writer, "人民是伟大祖国是伟大");
60      AddDocument(writer, "你站在边上我站在中央");
61      writer.Optimize;
62      writer.Close;
63    }
64    /**//// <summary>
65    /// 为索引准备数据
66    /// </summary>
67    /// <param name="writer">索引例子</param>
68    /// <param name="content">需要索引数据</param>
69    void AddDocument(IndexWriter writer, content)
70    {
71      Document document = Document;
72      document.Add( Field("content", content, Field.Store.YES, Field.Index.TOKENIZED));
73      writer.AddDocument(document);
74    }
75  }
76}
77


  代码2.1.2.1先是把 4句话进行了索引尔后分别用5个词进行了查询运行结果:

  搜索词:中华

  结果:

  中华人民共和国

  -----------------------------------

  搜索词:中国

  结果:

  中国人民解放军

  -----------------------------------

  搜索词:人民

  结果:

  中华人民共和国

  中国人民解放军

  人民是伟大祖国是伟大

  -----------------------------------

  搜索词:中国人民

  结果:

  中国人民解放军

  -----------------------------------

  搜索词:人民

  结果:

  中华人民共和国

  中国人民解放军

  人民是伟大祖国是伟大

  -----------------------------------

  发现结果还很不错结果都在我们预料的中StandardAnalyzer分词器很好啊!为什么说它不行呢?接着用StandardAnalyzer分词器为网站WebSite建立了索引然后开始使用问题就出现了用户输入往往不是个词而是几个词或者干脆就是句话把问题简化就用代码2.1.2.1作为模型假如现在索引进了 4句话变成这样:

  (1)、英语单词语法口语都很重要

  (2)、口语语法单词都是英语重要组成部分

  (3)、我们要学好英语不但要学语法单词还有口语

  (4)、对于学英语只掌握单词语法还是没办法跟别人沟通必须能说出流利口语

  假设我们要搜索这 4句话也用5中输入:

  (1)、英语

  (2)、语法

  (3)、单词

  (4)、口语

  (5)、英语单词

  测试结果对于输入1234前 4个关键词没问题而第5个只能搜索到个结果这就纳闷了明明每句话都包含了“英语”“单词”这两个词汇为什么不行呢?而把输入词换成“英语口语”更邪门!没了个结果都没有这是为什么呢?这个要从Lucene.Net查询表达式说起

  话说为了让Lucene.Net能灵活得搜索因此Lucene.Net引入了查询表达式就和T-Sql查询语句差不多只是表现代码不现在对代码2.1.2.1做个调整在Query query = parser.Parse(query);语句下面加句“Console.WriteLine(query.);”这个输出就是查询表达式而对于“英语单词”这个词代码2.1.2.1会把它解析为——content:"英 语 单 词"——意思是在content字段找“英”“语”,“单”,“词”这 4个字并且这 4个字要连在这显然不是我们想要而在用baidu或者google搜索时候如果输入多个词的间加上空格就不样了同样放到这里来试试把词变成“英语 单词”测试

  测试结果:

  搜索词:英语 单词

  结果:

  content:"英 语" content:"单 词"

  英语单词语法口语都很重要

  口语语法单词都是英语重要组成部分

  我们要学好英语不但要学语法单词还有口语

  对于学英语只掌握单词语法还是没办法跟别人沟通必须能说出流利口语

  -----------------------------------

  可以搜素到了而表达式也变成了——content:"英 语" content:"单 词"

  现在将面临新问题:如何才能把“英语单词”变成“英语 单词”你不能期望用户总会输入搜索关键词后逐个加上空格区分而事实上个新问题又产生了修正会产生另外两个前人说太正确了在这个例子里可能看不出来把例子换把上面第 4句话换成“好好学英语”

  测试结果:

  -----------------------------------

  搜索词:英语 单词

  结果:

  content:"英 语" content:"单 词"

  英语单词语法口语都很重要

  口语语法单词都是英语重要组成部分

  我们要学好英语不但要学语法单词还有口语

  好好学英语

  -----------------------------------

  “好好学英语”没有包含“单词”这个词但是却被搜索到了这是为什么?玩我了吧?嘿嘿那是——content:"英 语" content:"单 词"——这个表达式是或者关系要是变成并且关系是不是能解决问题呢?尝试手动改造下表达式把表达式变成“+content:"英 语" +content:"单 词"”测试:

  -----------------------------------

  搜索词:+content:"英 语" +content:"单 词"

  结果:

  +content:"英 语" +content:"单 词"

  英语单词语法口语都很重要

  口语语法单词都是英语重要组成部分

  我们要学好英语不但要学语法单词还有口语

  -----------------------------------

  very good !这个才是我们想要嘛!如何自己构造表达式这个还是留到第 4章来系统既然“+content:"英 语" +content:"单 词"”可以用那是不是“+content:"英" +content:"语" +content:"单"+content:"词"”也可以使用呢?嘿嘿自己试试看吧



Tags:  luceneinaction lucene lucene中文分词 lucene分词

延伸阅读

最新评论

发表评论