转自:http://blog.csdn.net/huaishu/article/details/8543236

本文介绍lucene区分大小的原因,和解决方案.关于lucene大小写敏感问题我总结一下:

1.对于分词的Field且使用了StandardAnalyzer等分析器进行索引,同时利用StandardAnalyzer进行搜索时,lucene不区分大小写.

2.对于不分词的Field是区分大小写的.

一.分词和不分词

为了能使Field字段参与搜索,那么该Field就必须被索引.Field的Index类型必须是:(ANALYZED或TOKENIZED)和(NOT_ANALYZED或UN_TOKENIZED).区别在于:前者表示分词,后者表示不分词.例如:"中国人",使用StandardAnalyzer分析器分词结果是:"中","国","人".而不分词是把"中国人"作为整体建索引.

二.StandardAnalyzer底层原理

  1. public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader)
  2. {
  3. TokenStream result = new StandardTokenizer(reader);
  4. result = new StandardFilter(result);
  5. result = new LowerCaseFilter(result);
  6. result = new StopFilter(result, stopSet);
  7. return result;
  8. }

这是StandardAnalyzer类的一段代码.LowerCaseFilter可知StandardAnalyzer在分词时会有转小写的操作.

建索引且分词时会被转小写.

  1. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  2. QueryParser parser = new QueryParser("title", new StandardAnalyzer());
  3. Query query = parser.Parse(string.Format("title:{0}", key));
  4. hits = searcher.Search(query);
  5. printResult(hits, query.ToString());

这是段利用QueryParser和StandardAnalyzer的搜索,同样有转小写的操作.

由于建索引是底层小写,搜索也是被小写化了.故使用这种方式从外观接口的角度来说是不区分大小写的.

三.不分词和TermQuery查询

由于Field没有分词,所以建索引时数据会保持原始大小写.

  1. Hits hits = null;
  2. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  3. TermQuery query = new TermQuery(new Term("name", key));
  4. hits = searcher.Search(query);
  5. printResult(hits, query.ToString());

这是一段使用TermQuery查询的方式.同样查询关键字是大写就大写,是小写就小写.

在这种使用情况下就会区分大小写.比如索引"abc",查询"Abc"就查不出来.

我的解决方案是:

建索引时小写化保存能,搜索时关键字小写化查询.

四.分词,不分词,StandardAnalyzer,TermQuery组合.

1.不一定建索引时使用StandardAnalyzer,搜索时也时用StandardAnalyzer或不分词和TermQuery查询.其实有很多组合.

2.不仅StandardAnalyzer底层小写化,还有别的分析器也是这样的.或者可以自定义分析器.

五.lucene区分大小写示例:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Lucene.Net.Documents;
  5. using Lucene.Net.Index;
  6. using Lucene.Net.Search;
  7. using Lucene.Net.Analysis;
  8. using Lucene.Net.Analysis.Standard;
  9. using Lucene.Net.QueryParsers;
  10. namespace IndexTest
  11. {
  12. class Program
  13. {
  14. static void Main(string[] args)
  15. {
  16. createIndex();
  17. searchNameByTermQuery("abc");
  18. searchTitleByTermQuery("abc");
  19. searchNameByTermQuery("ABC");
  20. searchTitleByTermQuery("ABC");
  21. searchNameByQueryParser("ABC");
  22. searchTitleByQueryParser("ABC");
  23. //修改后的解决方案
  24. createIndex2();
  25. searchNameByTermQuery2("ABC");
  26. Console.ReadLine();
  27. }
  28. public static void createIndex()
  29. {
  30. Document doc1 = new Document();
  31. Field field = null;
  32. field = new Field("name", "abc", Field.Store.YES, Field.Index.UN_TOKENIZED);
  33. doc1.Add(field);
  34. field = new Field("title", "abc", Field.Store.YES, Field.Index.TOKENIZED);
  35. doc1.Add(field);
  36. field = new Field("id", "1", Field.Store.YES, Field.Index.NO);
  37. doc1.Add(field);
  38. Document doc2 = new Document();
  39. field = new Field("name", "Abc", Field.Store.YES, Field.Index.UN_TOKENIZED);
  40. doc2.Add(field);
  41. field = new Field("title", "Abc", Field.Store.YES, Field.Index.TOKENIZED);
  42. doc2.Add(field);
  43. field = new Field("id", "2", Field.Store.YES, Field.Index.NO);
  44. doc2.Add(field);
  45. IndexWriter writer = new IndexWriter("c:\\java\\index", new StandardAnalyzer(), true);
  46. writer.AddDocument(doc1);
  47. writer.AddDocument(doc2);
  48. writer.Close();
  49. }
  50. public static void searchNameByTermQuery(string key)
  51. {
  52. Hits hits = null;
  53. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  54. TermQuery query = new TermQuery(new Term("name", key));
  55. hits = searcher.Search(query);
  56. printResult(hits, query.ToString());
  57. }
  58. public static void searchTitleByTermQuery(string key)
  59. {
  60. Hits hits = null;
  61. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  62. TermQuery query = new TermQuery(new Term("title", key));
  63. hits = searcher.Search(query);
  64. printResult(hits, query.ToString());
  65. }
  66. public static void searchNameByQueryParser(string key)
  67. {
  68. Hits hits = null;
  69. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  70. QueryParser parser = new QueryParser("name", new StandardAnalyzer());
  71. Query query = parser.Parse(string.Format("name:{0}",key));
  72. hits = searcher.Search(query);
  73. printResult(hits, query.ToString());
  74. }
  75. public static void searchTitleByQueryParser(string key)
  76. {
  77. Hits hits = null;
  78. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  79. QueryParser parser = new QueryParser("title", new StandardAnalyzer());
  80. Query query = parser.Parse(string.Format("title:{0}", key));
  81. hits = searcher.Search(query);
  82. printResult(hits, query.ToString());
  83. }
  84. public static void createIndex2()
  85. {
  86. Document doc1 = new Document();
  87. Field field = null;
  88. field = new Field("name", "abc".ToLower(), Field.Store.YES, Field.Index.UN_TOKENIZED);
  89. doc1.Add(field);
  90. field = new Field("title", "abc", Field.Store.YES, Field.Index.TOKENIZED);
  91. doc1.Add(field);
  92. field = new Field("id", "1", Field.Store.YES, Field.Index.NO);
  93. doc1.Add(field);
  94. Document doc2 = new Document();
  95. field = new Field("name", "Abc".ToLower(), Field.Store.YES, Field.Index.UN_TOKENIZED);
  96. doc2.Add(field);
  97. field = new Field("title", "Abc", Field.Store.YES, Field.Index.TOKENIZED);
  98. doc2.Add(field);
  99. field = new Field("id", "2", Field.Store.YES, Field.Index.NO);
  100. doc2.Add(field);
  101. IndexWriter writer = new IndexWriter("c:\\java\\index", new StandardAnalyzer(), true);
  102. writer.AddDocument(doc1);
  103. writer.AddDocument(doc2);
  104. writer.Close();
  105. }
  106. public static void searchNameByTermQuery2(string key)
  107. {
  108. Hits hits = null;
  109. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");
  110. TermQuery query = new TermQuery(new Term("name", key.ToLower()));
  111. hits = searcher.Search(query);
  112. printResult(hits, query.ToString());
  113. }
  114. public static void printResult(Hits hits, String key)
  115. {
  116. Console.WriteLine("查询 " + key);
  117. if (hits != null)
  118. {
  119. if (hits.Length() == 0)
  120. {
  121. Console.WriteLine("没有找到任何结果");
  122. }
  123. else
  124. {
  125. Console.WriteLine("找到" + hits.Length() + "个结果");
  126. for (int i = 0; i < hits.Length(); i++)
  127. {
  128. Document d = hits.Doc(i);
  129. String id = d.Get("id");
  130. Console.WriteLine(id.ToString() + "   ");
  131. }
  132. Console.WriteLine();
  133. }
  134. }
  135. }
  136. }
  137. }
 

lucene 区分大小写 问题以及解决方案的更多相关文章

  1. Solr和ES对比

    Solr与ES(ElasticSearch)对比 搜索引擎选择: Elasticsearch与Solr 搜索引擎选型调研文档 Elasticsearch简介* Elasticsearch是一个实时的分 ...

  2. 搜索引擎选择: Elasticsearch与Solr

    我用过这两种搜索引擎,但也仅仅是用过而已,没有非常深入研究,以下是我的看法 lucene是完全用java实现,而sphinx是支持java api.显然这两者是有差别的,用java实现的意义在于,你可 ...

  3. 在 Java 应用程序中使用 Elasticsearch

    如果您使用过 Apache Lucene 或 Apache Solr,就会知道它们的使用体验非常有趣.尤其在您需要扩展基于 Lucene 或 Solr 的解决方案时,您就会了解 Elasticsear ...

  4. 【转】搜索引擎选择: Elasticsearch与Solr

    原文地址:http://i.zhcy.tk/blog/elasticsearchyu-solr/ Elasticsearch简介 Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助 ...

  5. Elasticsearch与Solr

    公司之前有个用Lucene实现的伪分布式项目,实时性很差,后期数据量逐渐增大的时候,数据同步一次需要十几小时.当时项目重构考虑到的是Solr和ES,我参与的是Solr技术的预研.因为项目实时性要求很高 ...

  6. 全文检索选择-------- Elasticsearch与Solr

    Elasticsearch简介* Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据. 它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三 ...

  7. MySql查询不区分大小写解决方案(两种)

    当我们输入不管大小写都能查询到数据,例如:输入 aaa 或者aaA ,AAA都能查询同样的结果,说明查询条件对大小写不敏感. 解决方案一: 于是怀疑Mysql的问题.做个实验:直接使用客户端用sql查 ...

  8. 全文检索解决方案(lucene工具类以及sphinx相关资料)

    介绍两种全文检索的技术. 1.  lucene+ 中文分词(IK) 关于lucene的原理,在这里可以得到很好的学习. http://www.blogjava.net/zhyiwww/archive/ ...

  9. 无法识别的属性“targetFramework”。请注意属性名称区分大小写。错误分析以及解决方案

    我的配置文件中是这样写的,<compilation debug="true" targetFramework="4.0"> 发布在iis上出现了 “ ...

随机推荐

  1. ORACLE回收站机制介绍

    回收站概念 从ORACLE 10g开始,引入了一个叫回收站(Recycle Bin)的概念.它的全称叫Tablespace Recycle Bin.回收站实际是一个逻辑容器(逻辑区域),原理有点类似于 ...

  2. avalon复杂绑定

    样式操作:ms-css-样式名=“样式值”,ms-class ms-css-width="prop"(自动补px) ms-css-height="{{prop}}%&qu ...

  3. apache2添加模块和添加站点

    apache2添加模块和添加站点 linux下的apache2的目录和windows上的区别还是很大的,但是用起来却更方便了,详解请看另一篇文章http://www.cnblogs.com/wancy ...

  4. Unity 移动端触摸屏操作

    Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时,桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作,但如多点触屏等操作却是无法利用鼠标操作进行的.Unity的Input类 ...

  5. 《Linux内核分析》第一周 计算机是如何工作的?

    刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK ONE(2. ...

  6. Linux 安装 Nginx

    1. nginx的安装: 开始学习如何安装nginx,首先安装必要的软件: # yum install libtool # yum install -y gcc-c++ # yum install z ...

  7. WCF学习心得------(二)设计和实现服务协定

    设计和实现服务协定 创建服务协定—WCF术语 消息 消息是一个独立的数据单元,它可能由几个部分组成,包括消息正文和消息头. 服务 服务是一个构造,它公开一个或多个终结点,其中每个终结点都公开一个或多个 ...

  8. 前端神器 Firebug 2.0 新特性一览

    如果你从事Web前端方面的开发工作,那么对Firebug一定不会陌生,这是Firefox浏览器的一款插件,集HTML查看和编辑.Javascript控制台.网络状况监视器于一体,给Web开发者带来了极 ...

  9. POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)

    题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...

  10. 单独删除std::vector &lt;std::vector&lt;string&gt; &gt; 的所有元素

    下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...