2012-02-01 11 views
7

मैं कई दस्तावेजों के शीर्षकों को रोकने के लिए एक स्नोबॉल विश्लेषक का उपयोग कर रहा हूं। सब कुछ अच्छी तरह से काम करता है, लेकिन उनके कुछ quirks हैं।वाइल्डकार्ड और स्टेमिंग के संयोजन का उपयोग

उदाहरण:

"valv", "वाल्व", या "वाल्व" की खोज रिटर्न परिणामों के एक ही नंबर। यह समझ में आता है क्योंकि स्नोबॉल विश्लेषक सबकुछ नीचे "वाल्व" को कम कर देता है।

मैं वाइल्डकार्ड का उपयोग करते समय समस्याओं में भाग लेता हूं। "वाल्व *" या "वाल्व *" की खोज किसी भी परिणाम को वापस नहीं करती है। अपेक्षित के रूप में "वाल्व *" काम करता है।

मुझे समझ में आता है कि यह क्यों हो रहा है, लेकिन मुझे नहीं पता कि इसे कैसे ठीक किया जाए।

मैंने एक विश्लेषक लिखने के बारे में सोचा जो स्टेमड और गैर-स्टेमड टोकन स्टोर करता है। मूल रूप से दो विश्लेषकों को लागू करना और दो टोकन धाराओं को जोड़ना। लेकिन मुझे यकीन नहीं है कि यह एक व्यावहारिक समाधान है।

मैंने एनालिजिंगवर्कर पार्सर का उपयोग करने के बारे में भी सोचा, लेकिन मुझे नहीं पता कि इसे मल्टीफ़ील्ड क्वेरी पर कैसे लागू किया जाए। इसके अलावा, "वाल्व *" की खोज करते समय एनालिजिंगक्वायर पार्सर का उपयोग "वाल्व" के लिए परिणाम लौटाएगा और यह अपेक्षित व्यवहार नहीं है।

क्या वाइल्डकार्ड और स्टेमिंग एल्गोरिदम दोनों का उपयोग करने का "पसंदीदा" तरीका है?

उत्तर

7

मैं

  1. उपयोग दो एक है कि उपजी शब्दों से युक्त क्षेत्रों, इससे पहले कि यह हल करने के लिए 2 अलग दृष्टिकोण का इस्तेमाल किया, एक दूसरे शब्दों वाले कहते हैं द्वारा, StandardAnalyzer उत्पन्न। जब आप खोज क्वेरी को पार्स करते हैं, यदि यह "मानक" फ़ील्ड में वाइल्डकार्ड खोज है, तो स्टेमड शर्तों के साथ फ़ील्ड का उपयोग न करें। यदि आपके पास उपयोगकर्ता ल्यूसीन के क्वेरीपर्सर में सीधे अपने प्रश्न इनपुट करते हैं तो इसका उपयोग करना कठिन हो सकता है।

  2. कस्टम विश्लेषक और इंडेक्स ओवरलैपिंग टोकन लिखें। यह मूल रूप से का उपयोग कर इंडेक्स में उसी स्थिति में मूल शब्द और स्टेम को अनुक्रमणित करता है। सही तरीके से उपयोग करने के तरीके के बारे में कुछ उदाहरण प्राप्त करने के लिए आप SynonymFilter पर देख सकते हैं।

मैं समाधान # 2 पसंद करता हूं।

+0

+1, यह करने का यह सबसे स्वाभाविक तरीका है। –

1

मुझे नहीं लगता कि ऐसा करने के लिए एक आसान (और सही) है।

मेरा समाधान एक कस्टम क्वेरी पार्सर लिख रहा होगा जो सबसे लंबे समय तक स्ट्रिंग को इंडेक्स में और आपके खोज मानदंडों के लिए सामान्य स्ट्रिंग पाता है।

class MyQueryParser : Lucene.Net.QueryParsers.QueryParser 
{ 
    IndexReader _reader; 
    Analyzer _analyzer; 

    public MyQueryParser(string field, Analyzer analyzer,IndexReader indexReader) : base(field, analyzer) 
    { 
     _analyzer = analyzer; 
     _reader = indexReader; 
    } 

    public override Query GetPrefixQuery(string field, string termStr) 
    { 
     for(string longestStr = termStr; longestStr.Length>2; longestStr = longestStr.Substring(0,longestStr.Length-1)) 
     { 
      TermEnum te = _reader.Terms(new Term(field, longestStr)); 
      Term term = te.Term(); 
      te.Close(); 
      if (term != null && term.Field() == field && term.Text().StartsWith(longestStr)) 
      { 
       return base.GetPrefixQuery(field, longestStr); 
      } 
     } 

     return base.GetPrefixQuery(field, termStr); 
    } 
} 

आप भी GetPrefixQuery में अपने विश्लेषक कॉल करने के लिए जो PrefixQuery रों

TokenStream ts = _analyzer.TokenStream(field, new StringReader(termStr)); 
Lucene.Net.Analysis.Token token = ts.Next(); 
var termstring = token.TermText(); 
ts.Close(); 
return base.GetPrefixQuery(field, termstring); 

के लिए नहीं बुलाया जाता है लेकिन, ध्यान रखें कि आप हमेशा एक मामले में जहां लौटाए गए परिणाम सही नहीं हैं पा सकते हैं हो सकता है की कोशिश कर सकते हैं। यही कारण है कि वाइल्डकार्ड का उपयोग करते समय लुसीन विश्लेषकों को ध्यान में नहीं लेता है।

+0

मैं वास्तव में दो टोकनस्ट्रीम मर्ज करने का एक तरीका ढूंढना चाहता हूं, इसलिए मेरे पास टोकन का एक स्टेमड और गैर-स्टेमड सेट हो सकता है ... मैं इसे थोड़ा सा देखने जा रहा हूं। अगर मुझे कोई रास्ता मिल जाए तो मैं अपडेट करूंगा। दूसरे समाधान के लिए – SharpBarb

0

अन्य उत्तरों से परे एकमात्र संभावित विचार है कि दोनों क्षेत्रों के खिलाफ विघटन का उपयोग करें, ताकि आप केवल दो क्षेत्रों के सापेक्ष वजन निर्धारित कर सकें। एकमात्र चेतावनी यह है कि विघटन के कुछ संस्करण वाइल्डकार्ड को संभाल नहीं पाए थे, और कुछ पार्सर सौर विशिष्ट हैं।

1

यह सबसे सरल उपाय है और यह काम करेगा -

अपने 'सूचकांक' विश्लेषक में solr.KeywordRepeatFilterFactory जोड़ें।

http://lucene.apache.org/core/4_8_0/analyzers-common/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.html

इसके अलावा 'सूचकांक' विश्लेषक

अब

अपने सूचकांक में आप हमेशा उपजी होगा के अंत में RemoveDuplicatesTokenFilterFactory जोड़ सकते हैं और गैर एक ही स्थिति पर एक टोकन के लिए प्रपत्र उपजी और आप कर रहे हैं जाना अच्छा है।

संबंधित मुद्दे