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


    转自: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. }  
     
  • 相关阅读:
    js获取或设置当前窗口url参数
    ping域名怎么用?通过ping域名我们能看见什么?
    css中的zoom
    transition(属性渐变)、animation(动画)
    做一个input搜索框
    float 与 position 剪不断理还乱的关系
    PHP判断FORM来的数据是否为整数
    合并两个数组的两种方式的异同
    了解thinkphp(五)
    了解ThinkPHP(四)
  • 原文地址:https://www.cnblogs.com/duanweishi/p/5078545.html
Copyright © 2020-2023  润新知