转自: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. }
 

最新文章

  1. UVA232
  2. IOS数据存储之Sqlite数据库
  3. 使用 PHP 过滤器(Filter)进行严格表单验证
  4. GTC China 2016观感
  5. ASP.NET的路由
  6. 6-06. 理性任务调度(25)(拓扑排序啊 ZJU_PAT)
  7. SQL sever 创建定时执行任务
  8. Java静态代理与动态代理模式的实现
  9. php 设计模式之策略模式
  10. 使用Angularjs和Vue.js对比
  11. SharePoint客户端js对象模型
  12. JMeter二次开发环境配置
  13. XSS绕过小结
  14. 【汇编语言】Win10 安装 DOXBox0.74
  15. mysql锁分析相关的几个系统视图
  16. H5常用技巧
  17. EBS MOAC
  18. Win10下安装MySQL5.6
  19. Struts2 --简单留言系统
  20. linux通过speedtest-cli测试服务器网速

热门文章

  1. vs2005无法启动
  2. python 中 sorted() 和 list.sort() 的用法
  3. Mvc3.0_笔记
  4. 通过ros节点发布Twist Messages控制机器人--10
  5. ubuntu14.04 ibus pinyin wrong (ibus拼音乱拼问题)
  6. ArrayList线程不安全
  7. PHP 安装 eaccelerator
  8. spring源码学习之【准备】cglib动态代理例子
  9. python文件操作--字符串替换
  10. 【转】iOS基于WebSocket的聊天机制