2010-03-05 69 views
2

我正在建立一個包含特殊名稱的搜索索引 - 包含!和?和&和+和...我有踏下搜索不同:Lucene:通配符缺少索引

我&你

我+你

但無論我做什麼(沒有嘗試在索引之前的QueryParser逃脫,逃脫它手動,嘗試不同的索引...) - 如果我檢查與盧克搜索索引他們不顯示(問號和@ - 符號和類似的東西出現)

邏輯背後是我正在做部分搜索對於一個活的建議(和領域不那麼大),所以我把它分開到「m」和「me」和「+」和「y」和「yo」和「you」,然後索引它(這樣它比通配查詢搜索更快(並且索引大小不是一個大問題)。

所以我會需要的是也有這個特殊通配符插入索引。

這是我的代碼:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using Lucene.Net.Analysis; 
using Lucene.Net.Util; 

namespace AnalyzerSpike 
{ 
    public class CustomAnalyzer : Analyzer 
    { 
     public override TokenStream TokenStream(string fieldName, TextReader reader) 
     { 
      return new ASCIIFoldingFilter(new LowerCaseFilter(new CustomCharTokenizer(reader))); 
     } 
    } 

    public class CustomCharTokenizer : CharTokenizer 
    { 
     public CustomCharTokenizer(TextReader input) : base(input) 
     { 

     } 

     public CustomCharTokenizer(AttributeSource source, TextReader input) : base(source, input) 
     { 
     } 

     public CustomCharTokenizer(AttributeFactory factory, TextReader input) : base(factory, input) 
     { 
     } 

     protected override bool IsTokenChar(char c) 
     { 
      return c != ' '; 
     } 
    } 
} 

的代碼來創建索引:

private void InitIndex(string path, Analyzer analyzer) 
{ 
    var writer = new IndexWriter(path, analyzer, true); 

    //some multiline textbox that contains one item per line: 
    var all = new List<string>(txtAllAvailable.Text.Replace("\r","").Split('\n')); 

    foreach (var item in all) 
    { 
     writer.AddDocument(GetDocument(item)); 
    } 

    writer.Optimize(); 
    writer.Close(); 
} 

private static Document GetDocument(string name) 
{ 
    var doc = new Document(); 

    doc.Add(new Field(
     "name", 
     DeNormalizeName(name), 
     Field.Store.YES, 
     Field.Index.ANALYZED)); 

    doc.Add(new Field(
       "raw_name", 
       name, 
       Field.Store.YES, 
       Field.Index.NOT_ANALYZED)); 

    return doc; 
} 

(代碼是(Lucene.net版本1.9.x的編輯:對不起 - 爲2.9。 x),但與Java的Lucene兼容)

Thx

+0

你確定你的意思是1.9。*?你提到asciifoldingfilter這聽起來像一個2.9變種。 – 2010-03-05 21:30:42

+0

我應該補充一點,你所描述的內容聽起來很好,所以我懷疑你的分析器中沒有看到代碼中存在的問題。例如,你是否從另一個類派生它,而不是覆蓋所需的所有方法? – 2010-03-05 21:39:52

+0

對不起 - 你完全正確 - 它的2.9.x版 - thx! 我更新了我的問題,其中包括所有相關的代碼(非規範化代碼僅僅是一個自定義的方法添加了所有的空間用於更快的搜索。 – Eleasar 2010-03-07 17:46:51

回答

0

終於有時間再看一遍。在我的denormalice方法中,這是一個愚蠢的錯誤,它過濾掉了單個字符部分(因爲它在開始時),因此如果用空格包圍,它確實會過濾出加號: -/

Thx對於您的幫助Moleski!

private static string DeNormalizeName(string name) 
{ 
    string answer = string.Empty; 

    var wordsOnly = Regex.Replace(name, "[^\\w0-9 ]+", string.Empty); 
    var filterText = (name != wordsOnly) ? name + " " + wordsOnly : name; 

    foreach (var subName in filterText.Split(' ')) 
    { 
     if (subName.Length >= 1) 
     { 
      for (var j = 1; j <= subName.Length; j++) 
      { 
       answer += subName.Substring(0, j) + " "; 
      } 
     } 
    } 
    return answer.TrimEnd(); 
} 
+0

我正在學習如何做這我自己,你覺得你能爲發佈代碼的非規範化方法我不清楚,做在這一點上有什麼 感謝 – Matt 2010-03-30 00:26:01

+0

更新我的答案 - ?。但是這是沒有代碼特定於Lucene的 - 它只是我的特殊情況(和它只是一個秒殺 - 所以如果你想簡單的搜索不要指望完美的代碼) - 。然後忘掉我的非規範化方法,它只是在我的特殊情況,加快現場建議用作通配符搜索是小言相當昂貴的 - 我想要顯示以第一個字母或第二個字母開頭的建議。 – Eleasar 2010-03-30 09:00:56