2011-11-23 13 views
5

मैं "ए" और "बी" नामक दो क्षेत्रों में अपनी अनुक्रमणिका खोजना चाहता हूं। मैं Freud -- theories of psychology तरह की खोजों दिया हूँ और मैं निम्न क्वेरी प्रदर्शन करने के लिए करना चाहते हैं:मैं या दो का उपयोग कर दो ल्यूसीन प्रश्नों को कैसे जोड़ूं?

(a="Freud" AND b="theories of psychology") OR (b="Freud" AND a="theories of psychology") 

मैं यह करने के लिए कैसे करते हैं? अब तक मैं Lucene दो हिस्सों (firstHalf और secondHalf) MultiFieldQueryParser का उपयोग कर निर्माण है, तो मैं उन्हें

BooleanQuery combined = new BooleanQuery(); 
combined.add(firstHalf, BooleanClause.Occur.SHOULD); 
combined.add(secondHalf, BooleanClause.Occur.SHOULD); 

लेकिन combined के साथ संयुक्त कर दिया है की अनुमति देता है, जहां केवल "सिद्धांत" "मनोविज्ञान" पाया जाता है और नहीं परिणामों वापस करने , जहां मैं निश्चित रूप से दोनों शर्तों को चाहता हूँ। ऐसा लगता है जैसे ल्यूसीन "मनोविज्ञान की सिद्धांतों" को तीन शब्दों में विभाजित कर रहा है और उन्हें व्यक्तिगत रूप से OR के साथ संयोजित कर रहा है। मैं इसे कैसे न होने दूँ?

firstHalf लगता है:

Query firstHalf = MultiFieldQueryParser.parse(Version.LUCENE_33, 
     new String[]{"Freud", "theories of psychology"}, 
     new String[]{"a", "b"}, 
     new BooleanClause.Occur[]{BooleanClause.Occur.MUST, BooleanClause.Occur.MUST}, 
     analyzer); 

जहां analyzer सिर्फ एक StandardAnalyzer वस्तु है।

+0

बस बताया गया था कि Lucene इस तरह बूलियन तर्क का समर्थन नहीं करता है, और उस चाहिए = या!। उस स्थिति में, पृष्ठ 95 पर _Lucene एक्शन_ 2 संस्करण में गलत है। :) तो अब मुझे पता है कि मेरी क्वेरी टूटी हुई है, सिर्फ यह नहीं पता कि इसे अभी कैसे ठीक किया जाए। – dmn

+0

क्या आप वाकई क्वेरी सही हैं? प्रश्न 'मनोविज्ञान के सिद्धांत' का अर्थ है कि कम से कम तीन शब्दों में से एक होना चाहिए, लेकिन उनमें से कोई भी एक आवश्यक शब्द नहीं है। –

+0

@KaiChan नहीं, मुझे उस प्रतिबंध को रोकने के लिए इसे संशोधित करना पड़ा। मुझे लगता है कि मुझे यह मिला है। :) – dmn

उत्तर

2

मानक विश्लेषक टोकननाइजेशन करेगा। तो क्वेरी theories of psychologytheories OR of OR psychology के बराबर है।

आप वाक्यांश "मनोविज्ञान के सिद्धांतों" के लिए खोज करना चाहते हैं एक PhraseQuery का उपयोग, वरना ध्यान दें कि डिफ़ॉल्ट QueryParser एक मुहावरा है जिसका अर्थ है के रूप में उद्धरण की व्याख्या करेगा (अर्थात अपने कोड बदलने "\"theories of psychology\"" होने के लिए)।

और हां, एक ऐसी भावना है जिसमें लुसीन बूलियन तर्क का उपयोग नहीं करता है, लेकिन यह तकनीकी है और यहां वास्तव में प्रासंगिक नहीं है।

3

इसे स्वयं समझ लिया, लेकिन अब कोड काफी लंबा है; अगर कोई और अधिक सुरुचिपूर्ण समाधान जानता है, तो कृपया पोस्ट करें और मैं खुशी से इनाम दूंगा। :) (मैं शीघ्र ही एक विधि में इस बनाएंगे, हालांकि ... लेकिन यहाँ क्या हो रहा है के पूर्ण संस्करण है ...)

QueryParser parser = new QueryParser(Version.LUCENE_33, "a", analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 
Query a_0 = parser.parse("Freud"); 
parser = new QueryParser(Version.LUCENE_33, "b", analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 
Query b_1 = parser.parse("theories of psychology"); 

BooleanQuery firstHalf = new BooleanQuery(); 
firstHalf.add(a_0, BooleanClause.Occur.MUST); 
firstHalf.add(b_1, BooleanClause.Occur.MUST); 

parser = new QueryParser(Version.LUCENE_33, "b", analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 
Query b_0 = parser.parse("Freud"); 
parser = new QueryParser(Version.LUCENE_33, "a", analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 
Query a_1 = parser.parse("theories of psychology"); 

BooleanQuery secondHalf = new BooleanQuery(); 
secondHalf.add(b_0, BooleanClause.Occur.MUST); 
secondHalf.add(a_1, BooleanClause.Occur.MUST); 

BooleanQuery combined = new BooleanQuery(); 
combined.add(firstHalf, BooleanClause.Occur.SHOULD); 
combined.add(secondHalf, BooleanClause.Occur.SHOULD); 

बाहर कर देता है SHOULD तरह से मैं यहाँ के लिए इसकी आवश्यकता काम करता है। उम्मीद है कि किसी को यह सहायक लगता है और मैं सिर्फ जनता में बात नहीं कर रहा हूं;)

+1

यह मेरा हालिया अनुभव है कि लुसीन सीखने में, आपको क्वेरीपर्सर से बचना चाहिए और सीधे अंतर्निहित क्वेरी प्रकारों से सबकुछ टुकड़ा करने का प्रयास करना चाहिए। आपको लुसीन की बेहतर समझ मिलेगी और क्वेरी सिंटैक्स द्वारा विचलित नहीं होगी। जैसा कि Xodarap का उल्लेख है, आप वास्तव में यहां क्या चाहते हैं PhraseQuery है।आपके पास अब क्या है किसी भी क्रम या स्थिति में "मनोविज्ञान" के "सिद्धांत" "के साथ दस्तावेजों से मेल खाता है, सटीक वाक्यांश नहीं। (असल में, मानक विश्लेषक "का" फ़िल्टर करेंगे, इसलिए PhraseQuery भी आपके सटीक वाक्यांश से मेल नहीं खाएगा ... लेकिन यह खोज की एक सीमा है जिसे हम आम तौर पर स्वीकार करते हैं।) – Jegschemesch

2

मैंने कक्षा के नीचे जंजीर अस्पष्ट प्रश्न उत्पन्न करने के लिए लिखा है जहां कई क्षेत्रों में एक शब्द खोजा जाना है। GetQuery() विधि पर कॉल करके संयुक्त क्वेरी को पुनर्प्राप्त किया जा सकता है।

public class QueryParam 
{ 
    public string[] Fields { get; set; } 
    public string Term { get; set; } 

    private QueryParam _andOperandSuffix; 
    private QueryParam _orOperandSuffix; 

    private readonly BooleanQuery _indexerQuery = new BooleanQuery();   

    public QueryParam(string term, params string[] fields) 
    { 
     Term = term; 
     Fields = fields; 
    } 

    public QueryParam And(QueryParam queryParam) 
    { 
     _andOperandSuffix = queryParam; 
     return this; 
    } 

    public QueryParam Or(QueryParam queryParam) 
    { 
     _orOperandSuffix = queryParam; 
     return this; 
    } 

    public BooleanQuery GetQuery() 
    {    
     foreach (var field in Fields) 
      _indexerQuery.Add(new FuzzyQuery(new Term(field, Term)), Occur.SHOULD); 

     if (_andOperandSuffix != null) 
      _indexerQuery.Add(_andOperandSuffix.GetQuery(),Occur.MUST); 

     if (_orOperandSuffix != null) 
      _indexerQuery.Add(_orOperandSuffix.GetQuery(), Occur.SHOULD); 

     return _indexerQuery; 
    } 

} 

उदाहरण:

var leftquery = new QueryParam("Freud", "a").And(new QueryParam("theories of psychology", "b")); 
var rightquery = new QueryParam("Freud", "b").And(new QueryParam("theories of psychology", "a")); 
var query = leftquery.Or(rightquery);    
संबंधित मुद्दे