2013-03-08 12 views
7

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

क्वेरी बिल्डर:

QueryBuilder qBuilder = fullTextSession.getSearchFactory() 
     .buildQueryBuilder().forEntity(LearningGoal.class).get(); 
    Query query = qBuilder.keyword().wildcard().onField("title") 
     .matching(searchString + "*").createQuery(); 

    BooleanQuery bQuery = new BooleanQuery(); 
    bQuery.add(query, BooleanClause.Occur.MUST); 
    for (LearningGoal exGoal : existingGoals) { 
    Term omittedTerm = new Term("id", String.valueOf(exGoal.getId())); 
    bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT); 
    } 
    @SuppressWarnings("unused") 
    org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
     query, LearningGoal.class); 

हाइबरनेट वर्ग:

@AnalyzerDef(name = "searchtokenanalyzer",tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), 
filters = { 
    @TokenFilterDef(factory = StandardFilterFactory.class), 
    @TokenFilterDef(factory = LowerCaseFilterFactory.class), 
    @TokenFilterDef(factory = StopFilterFactory.class,params = { 
     @Parameter(name = "ignoreCase", value = "true") }) }) 
     @Analyzer(definition = "searchtokenanalyzer") 
public class LearningGoal extends Node { 
+0

उत्पादन के लिए क्वेरी मुद्रण निश्चित रूप से मदद मिलेगी है .. – phani

+0

यह वास्तव में उपयोगी है, लेकिन मुझे मदद नहीं की समझने के लिए कारण है कि मैं परिणाम नहीं है। उदाहरण के लिए, मेरे पास सीखने का लक्ष्य है जिसका शीर्षक "लर्निंग प्रॉबिलिटी थ्योरी" है। दो प्रश्नों का उत्पादन ** bQuery: + शीर्षक: सीखना पी * hibQuery: पूर्ण स्ट्रक्चरक्वाइम (शीर्षक: सीखना पी *) ** इनपुट स्ट्रिंग "सीखने पी" ​​के लिए **। इनपुट स्ट्रिंग "सीखना" है तो यह मूल्य पाता है। –

+0

मैंने अंतरिक्ष को प्रतिस्थापित करने का भी प्रयास किया?, लेकिन इससे परिणाम नहीं मिला। –

उत्तर

7

मैं इस समस्या के लिए समाधान का पाया साथ matching(searchString + "*") को बदलने के लिए। विचार इनपुट स्ट्रिंग को टोकन करना और स्टॉप शब्दों को निकालना है। अंतिम टोकन के लिए मैंने कीवर्ड वाइल्डकार्ड का उपयोग करके एक क्वेरी बनाई, और पिछले सभी शब्दों के लिए मैंने टर्मक्वायर बनाया। यहाँ पूर्ण कोड

BooleanQuery bQuery = new BooleanQuery(); 
    Session session = persistence.currentManager(); 
    FullTextSession fullTextSession = Search.getFullTextSession(session); 
    Analyzer analyzer = fullTextSession.getSearchFactory().getAnalyzer("searchtokenanalyzer"); 
    QueryParser parser = new QueryParser(Version.LUCENE_35, "title", analyzer); 
    String[] tokenized=null; 
    try { 
    Query query= parser.parse(searchString); 
    String cleanedText=query.toString("title"); 
    tokenized = cleanedText.split("\\s"); 

    } catch (ParseException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    QueryBuilder qBuilder = fullTextSession.getSearchFactory() 
      .buildQueryBuilder().forEntity(LearningGoal.class).get(); 
    for(int i=0;i<tokenized.length;i++){ 
     if(i==(tokenized.length-1)){ 
      Query query = qBuilder.keyword().wildcard().onField("title") 
        .matching(tokenized[i] + "*").createQuery(); 
       bQuery.add(query, BooleanClause.Occur.MUST); 
     }else{ 
      Term exactTerm = new Term("title", tokenized[i]); 
      bQuery.add(new TermQuery(exactTerm), BooleanClause.Occur.MUST); 
     } 
    } 
     for (LearningGoal exGoal : existingGoals) { 
     Term omittedTerm = new Term("id", String.valueOf(exGoal.getId())); 
     bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT); 
    } 
    org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
      bQuery, LearningGoal.class); 
+0

जैसा नहीं है क्या आप अधिक स्पष्टीकरण जोड़ सकते हैं? मुझे अब तक यह नहीं मिला है। आखिरी टोकन के लिए आप एक अलग क्वेरी का उपयोग क्यों कर रहे हैं? और कृपया अपना उदाहरण संशोधित करें, कि यह पर्याप्त स्पष्ट है। 'मौजूदागोल्स 'क्यों आवश्यक हैं? – alexander

+0

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

+0

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

-1

एसक्यूएल किसी भी टर्मिनल की तुलना में अलग वाइल्डकार्ड का उपयोग करता है। एसक्यूएल '%' में किसी भी चरित्र की शून्य या अधिक घटनाओं को प्रतिस्थापित करता है (टर्मिनल में आप '*' इसके बजाय उपयोग करते हैं), और अंडरस्कोर '_' बिल्कुल एक वर्ण को प्रतिस्थापित करता है (टर्मिनल में आप इसके बजाय '?' का उपयोग करते हैं)। हाइबरनेट वाइल्डकार्ड वर्णों का अनुवाद नहीं करता है।

तो दूसरी पंक्ति में आप

matching(searchString + "%") 
+0

क्या आप इस बारे में निश्चित हैं? इसके बाद यह मुझे खोजस्ट्रिंग में रिक्त स्थान के बिना भी कोई परिणाम नहीं देता है। पहले (* के साथ) मेरे पास कुछ परिणाम थे जब तक कि खोज स्ट्रिंग में नहीं आती। मुझे नहीं पता कि यह हाइबरनेट खोज एसक्यूएल से कैसे संबंधित है? यह ल्यूसीन इंडेक्स पर खोज करता है जो डेटाबेस में संग्रहीत नहीं होते हैं, इसलिए मुझे यकीन नहीं है कि यह SQL वाक्यविन्यास का उपयोग करता है या नहीं। –

+0

हाइबरनेट + एसक्यूएल के लिए मुझे यकीन है, लेकिन मैं लुसीन का उपयोग नहीं करता, और मुझे नहीं पता कि ल्यूसीन इंजन इनपुट के साथ क्या कर रहा है। – Johanna

+0

मैं देखता हूं। आपने सोचा कि यह नियमित डेटाबेस क्वेरी है। हालांकि, हाइबरनेट खोज ल्यूसीन इंडेक्स पर खोजने के लिए लुसीन प्रश्नों का उपयोग करती है और इसका वाक्यविन्यास एसक्यूएल http://www.lucenetutorial.com/lucene-query-syntax.html –

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