lucene 区分大小写 问题以及解决方案

时间:2023-01-31 00:52:41

转自: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.   
  3. QueryParser parser = new QueryParser("title", new StandardAnalyzer());  
  4. Query query = parser.Parse(string.Format("title:{0}", key));  
  5.   
  6. hits = searcher.Search(query);  
  7. printResult(hits, query.ToString());  

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

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

三.不分词和TermQuery查询 

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

  1. Hits hits = null;  
  2.   
  3. IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  4.   
  5. TermQuery query = new TermQuery(new Term("name", key));  
  6.   
  7. hits = searcher.Search(query);  
  8. 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.   
  11. namespace IndexTest  
  12. {  
  13.     class Program  
  14.     {  
  15.         static void Main(string[] args)  
  16.         {  
  17.             createIndex();  
  18.             searchNameByTermQuery("abc");  
  19.             searchTitleByTermQuery("abc");  
  20.   
  21.             searchNameByTermQuery("ABC");  
  22.             searchTitleByTermQuery("ABC");  
  23.   
  24.             searchNameByQueryParser("ABC");  
  25.             searchTitleByQueryParser("ABC");  
  26.   
  27.             //修改后的解决方案  
  28.             createIndex2();  
  29.             searchNameByTermQuery2("ABC");  
  30.   
  31.             Console.ReadLine();  
  32.         }  
  33.   
  34.         public static void createIndex()  
  35.         {  
  36.             Document doc1 = new Document();  
  37.             Field field = null;  
  38.             field = new Field("name", "abc", Field.Store.YES, Field.Index.UN_TOKENIZED);  
  39.             doc1.Add(field);  
  40.             field = new Field("title", "abc", Field.Store.YES, Field.Index.TOKENIZED);  
  41.             doc1.Add(field);  
  42.             field = new Field("id", "1", Field.Store.YES, Field.Index.NO);  
  43.             doc1.Add(field);  
  44.   
  45.             Document doc2 = new Document();  
  46.             field = new Field("name", "Abc", Field.Store.YES, Field.Index.UN_TOKENIZED);  
  47.             doc2.Add(field);  
  48.             field = new Field("title", "Abc", Field.Store.YES, Field.Index.TOKENIZED);  
  49.             doc2.Add(field);  
  50.             field = new Field("id", "2", Field.Store.YES, Field.Index.NO);  
  51.             doc2.Add(field);           
  52.   
  53.               
  54.             IndexWriter writer = new IndexWriter("c:\\java\\index", new StandardAnalyzer(), true);  
  55.   
  56.             writer.AddDocument(doc1);  
  57.             writer.AddDocument(doc2);  
  58.    
  59.   
  60.             writer.Close();  
  61.         }  
  62.   
  63.   
  64.   
  65.   
  66.         public static void searchNameByTermQuery(string key)  
  67.         {  
  68.              
  69.             Hits hits = null;  
  70.   
  71.             IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  72.   
  73.             TermQuery query = new TermQuery(new Term("name", key));  
  74.               
  75.             hits = searcher.Search(query);  
  76.             printResult(hits, query.ToString());  
  77.         }  
  78.   
  79.         public static void searchTitleByTermQuery(string key)  
  80.         {  
  81.   
  82.             Hits hits = null;  
  83.   
  84.             IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  85.   
  86.             TermQuery query = new TermQuery(new Term("title", key));  
  87.   
  88.             hits = searcher.Search(query);  
  89.             printResult(hits, query.ToString());  
  90.         }  
  91.   
  92.         public static void searchNameByQueryParser(string key)  
  93.         {  
  94.   
  95.             Hits hits = null;  
  96.             IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  97.   
  98.             QueryParser parser = new QueryParser("name", new StandardAnalyzer());              
  99.             Query query = parser.Parse(string.Format("name:{0}",key));  
  100.   
  101.             hits = searcher.Search(query);  
  102.             printResult(hits, query.ToString());  
  103.         }  
  104.   
  105.         public static void searchTitleByQueryParser(string key)  
  106.         {  
  107.   
  108.             Hits hits = null;  
  109.   
  110.             IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  111.   
  112.             QueryParser parser = new QueryParser("title", new StandardAnalyzer());  
  113.             Query query = parser.Parse(string.Format("title:{0}", key));  
  114.   
  115.             hits = searcher.Search(query);  
  116.             printResult(hits, query.ToString());  
  117.         }  
  118.   
  119.   
  120.   
  121.         public static void createIndex2()  
  122.         {  
  123.             Document doc1 = new Document();  
  124.             Field field = null;  
  125.             field = new Field("name", "abc".ToLower(), Field.Store.YES, Field.Index.UN_TOKENIZED);  
  126.             doc1.Add(field);  
  127.             field = new Field("title", "abc", Field.Store.YES, Field.Index.TOKENIZED);  
  128.             doc1.Add(field);  
  129.             field = new Field("id", "1", Field.Store.YES, Field.Index.NO);  
  130.             doc1.Add(field);  
  131.   
  132.             Document doc2 = new Document();  
  133.             field = new Field("name", "Abc".ToLower(), Field.Store.YES, Field.Index.UN_TOKENIZED);  
  134.             doc2.Add(field);  
  135.             field = new Field("title", "Abc", Field.Store.YES, Field.Index.TOKENIZED);  
  136.             doc2.Add(field);  
  137.             field = new Field("id", "2", Field.Store.YES, Field.Index.NO);  
  138.             doc2.Add(field);  
  139.   
  140.   
  141.             IndexWriter writer = new IndexWriter("c:\\java\\index", new StandardAnalyzer(), true);  
  142.   
  143.             writer.AddDocument(doc1);  
  144.             writer.AddDocument(doc2);  
  145.   
  146.   
  147.             writer.Close();  
  148.         }  
  149.   
  150.         public static void searchNameByTermQuery2(string key)  
  151.         {  
  152.   
  153.             Hits hits = null;  
  154.   
  155.             IndexSearcher searcher = new IndexSearcher("c:\\java\\index");  
  156.   
  157.             TermQuery query = new TermQuery(new Term("name", key.ToLower()));  
  158.   
  159.             hits = searcher.Search(query);  
  160.             printResult(hits, query.ToString());  
  161.         }  
  162.   
  163.   
  164.   
  165.          public static void printResult(Hits hits, String key)    
  166.      {    
  167.          Console.WriteLine("查询 " + key);    
  168.          if (hits != null)    
  169.          {    
  170.              if (hits.Length() == 0)    
  171.              {    
  172.                  Console.WriteLine("没有找到任何结果");    
  173.              }    
  174.              else    
  175.              {    
  176.                  Console.WriteLine("找到" + hits.Length() + "个结果");    
  177.                  for (int i = 0; i < hits.Length(); i++)    
  178.                  {    
  179.                      Document d = hits.Doc(i);    
  180.                      String id = d.Get("id");    
  181.                      Console.WriteLine(id.ToString() + "   ");    
  182.                  }    
  183.                  Console.WriteLine();                     
  184.              }    
  185.          }    
  186.      }    
  187.  }       
  188.      
  189. }