2012-12-17 12 views
8

के साथ कई फ़ील्ड खोजना उपयोगकर्ताओं को लुसीन 3.5 के साथ कई फ़ील्ड में खोजने की अनुमति देने के लिए वर्तमान में DisjunctionMaxQuery पर प्रत्येक फ़ील्ड को खोजने के लिए QueryParser जोड़ें और जोड़ें। या का उपयोग डिफ़ॉल्ट ऑपरेटर के रूप में करते समय यह बहुत अच्छा काम करता है लेकिन अब मैं अधिक सटीक (और कम) परिणाम प्राप्त करने के लिए डिफ़ॉल्ट ऑपरेटर को और में बदलना चाहता हूं।लुसीन: डिफ़ॉल्ट ऑपरेटर = और

समस्या है, queryParser.setDefaultOperator(QueryParser.AND_OPERATOR) कई दस्तावेजों को याद करता है क्योंकि सभी शर्तें कम से कम 1 फ़ील्ड में होनी चाहिए।

उदाहरण के लिए, दस्तावेज़ के लिए निम्न डेटा पर विचार करें: शीर्षक फ़ील्ड = "प्रोग्रामिंग भाषाएं", बॉडी फ़ील्ड = "जावा, सी ++, PHP"। यदि कोई उपयोगकर्ता जावा प्रोग्रामिंग खोजना चाहता था तो इस विशेष दस्तावेज़ को परिणामों में शामिल नहीं किया जाएगा क्योंकि शीर्षक और न ही शरीर के क्षेत्र में क्वेरी में सभी शर्तें शामिल हैं, हालांकि वे संयुक्त करते हैं। मैं चाहता हूं कि यह दस्तावेज़ उपरोक्त क्वेरी के लिए वापस लौटाए लेकिन क्वेरी एचटीएमएल प्रोग्रामिंग के लिए नहीं।

मैंने एक पकड़ क्षेत्र माना है लेकिन मुझे इसके साथ कुछ समस्याएं हैं। सबसे पहले, उपयोगकर्ता अक्सर अपने प्रश्नों (लेखक: बिल) में प्रति फ़ील्ड शर्तों को शामिल करते हैं जो कैचॉल फ़ील्ड के साथ संभव नहीं है। इसके अलावा, मैं फास्ट वेक्टर हाइलाइटर के साथ कुछ फ़ील्ड को हाइलाइट करता हूं जिसके लिए उन्हें अनुक्रमित और संग्रहीत करने की आवश्यकता होती है। तो एक कैचल फील्ड जोड़कर मुझे उसी डेटा के दो बार इंडेक्स करना होगा जो समय और स्थान लेने वाला है।

कोई विचार?

+0

कैचॉल फ़ील्ड को अनुक्रमणित करने के संबंध में, क्या आपने समय/स्पेस हिट देखी है जो चिंता का कारण है? मेरा अनुभव एक विशिष्ट संग्रहित फ़ील्ड में एक ही डेटा को अनुक्रमणित कर रहा है, और उसके बाद एक सामान्यीकृत इंडेक्स-केवल फ़ील्ड में जोड़ना प्रदर्शन या अनुक्रमणिका आकार पर बहुत कम प्रभाव डालता है। – femtoRgon

+0

इसके अलावा, मुझे आश्चर्य है कि अंत क्वेरी की संरचना कैसी दिखती है। विशेष रूप से, कैसे अधिकतम प्रश्न सेट अप किए जाते हैं। उनके साथ सार्थक स्कोर प्राप्त करने की अपनी क्षमता को मारना आसान है। – femtoRgon

+0

@femtoRgon disjunctionMaxQuery संरचना इस तरह है: '(शीर्षक: जावा शीर्षक: प्रोग्रामिंग) | (शरीर: जावा बॉडी: प्रोग्रामिंग)) ~ 0.2' आप एक अच्छा मुद्दा लाते हैं कि एक पकड़ने वाले क्षेत्र को जोड़ने से अब तक बहुत कम प्रभाव पड़ सकता है/अंतरिक्ष चिंतित है। मैंने निश्चित रूप से इसे माना लेकिन इसके खिलाफ फैसला किया क्योंकि मैं क्षेत्र द्वारा खोज करने की क्षमता को भी रखना चाहूंगा, जैसे लेखक: बिल। न केवल उपयोगकर्ता इस सुविधा का उपयोग करते हैं बल्कि मैं दृश्यों के पीछे इसका उपयोग करता हूं। धन्यवाद। –

उत्तर

6

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

String[] fields = {"title", "body", "subject", "author"}; 
QueryParser[] parsers = new QueryParser[fields.length];  
for(int i = 0; i < parsers.length; i++) 
{ 
    parsers[i] = new QueryParser(Version.LUCENE_35, fields[i], analyzer); 
    parsers[i].setDefaultOperator(QueryParser.AND_OPERATOR); 
} 

यह इस तरह एक प्रश्न में परिणाम होगा:

(+title:java +title:programming) | (+body:java +body:programming) 

... जो मैं क्या था नहीं है जो भी कारण मैं प्रत्येक क्षेत्र के लिए एक QueryParser निर्माण कर रहा है के लिए मैं इस तरह खोज करने के लिए करना चाहता था देख। अब मैं इस तरह एक भी MultiFieldQueryParser बनाएँ:

MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_35, new String[]{"title", "body", "subject"}, analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 

यह मैं क्वेरी मैं खोज रहा था देता है:

+(title:java body:java) +(title:programming body:programming) 

@seeta और @femtoRgon मदद के लिए धन्यवाद!

2

शायद आपको जो चाहिए वह बूलियन प्रश्नों का संयोजन है जो फ़ील्ड और शर्तों के विभिन्न संयोजनों को कैप्चर करता है। आपके दिए गए उदाहरण में, क्वेरी हो सकती है -

(शीर्षक: जावा और बॉडी: प्रोग्रामिंग) या (शीर्षक: प्रोग्रामिंग और बॉडी: जावा)।

मुझे नहीं पता कि कोई मौजूदा क्वेरी क्लास है जो स्वचालित रूप से आपके लिए उत्पन्न करती है, लेकिन मुझे लगता है कि इंडेक्स पर चलने वाली अंतिम क्वेरी क्या होनी चाहिए।

+0

मुझे लगता है कि आप सही रास्ते पर हैं हालांकि मुझे लगता है कि एंड्रॉइड और ओआर के आसपास स्विच करना बेहतर होगा? (शीर्षक: जावा या शरीर: जावा या विषय: जावा) और (शीर्षक: प्रोग्रामिंग या शरीर: प्रोग्रामिंग या विषय: प्रोग्रामिंग) ... [अतिरिक्त शर्तों को संसाधित करें] ... जब मैं दूसरों की तलाश में हूं तो मैं अपना कार्यान्वयन पोस्ट करूंगा एक संभावित समाधान। उत्तर के लिए Thx। –

0

आप अपनी टिप्पणी से मामले के एक ही सेट के साथ कई क्षेत्रों खोज करने के लिए है, तो सवाल सक्षम होना चाहते हैं:

((title:java title:programming) | (body:java body:programming))~0.2 

सबसे अच्छा कार्यान्वयन नहीं हो सकता है।

आप प्रभावी रूप से शीर्षक से स्कोर प्राप्त कर रहे हैं, या शब्दों के संयुक्त सेट के लिए शरीर से स्कोर प्राप्त कर रहे हैं। जिस मामले में आपने शरीर में शीर्षक और प्रोग्रामिंग में जावा मारा था, वह लगभग दिया जाएगा। शरीर में जावा पर एक हिट के बराबर वजन और प्रोग्रामिंग पर कोई हिट नहीं।

मुझे लगता है कि एक बेहतर संरचित क्वेरी होगा:

(title:java body:java)~0.2 (title:programming body:programming)~0.2 

यह मेरे लिए अधिक समझ में आता है आप dismax प्रश्नों स्कोर एक ही अवधि के कई प्रश्नों पर बढ़ सीमित करने के लिए (विभिन्न क्षेत्रों में) चाहते हैं के बाद से, लेकिन आप विभिन्न शर्तों पर हिट के लिए बढ़ने के लिए स्कोरिंग करना चाहते हैं, मुझे विश्वास है।

यदि उस प्रकार की क्वेरी संरचना आपको बेहतर स्कोर परिणाम प्राप्त करती है, तो परिणाम को सीमित करने के लिए एक निश्चित न्यूनतम स्कोर (एक साधारण हार्ड-कोडेड मान के बजाय लौटाए गए अधिकतम स्कोर का प्रतिशत) बहुत कमजोर नतीजों को रोकने के लिए पर्याप्त हो सकता है देखा जा रहा है।


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

तुम सच में यकीन है कि यह कम से कम रखने की जगह लेता है, तुम भी बंद TermVectors है कि क्षेत्र के लिए बंद कर सकते हैं होना चाहते हैं:

new Field(name, value, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO); 

हालांकि मैं एक अंतर यह है कि वास्तव में कैसे बनाया जाए कितना पता नहीं है।

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