2015-11-25 5 views
6

मैं जेपीए 2.1 (हाइबरनेट 4 के रूप में इम्प्लायर) और स्प्रिंग डेटा जेपीए 1.9.0 का उपयोग कर रहा हूं। मैं पूर्ण पाठ खोज कैसे कार्यान्वित करूं?जेपीए (स्प्रिंग डेटा जेपीए) में सरल पूर्ण पाठ खोज को कैसे कार्यान्वित करें?

मेरा परिदृश्य इस प्रकार है। मेरे पास User इकाई है और यूआई पर एक टेबल है जो अधिकांश उपयोगकर्ताओं के गुण प्रदर्शित करती है और मैं चाहता हूं कि उपयोगकर्ता टेक्स्ट बॉक्स दे, वहां एक खोज शब्द दर्ज करें और सभी गुणों में खोजें। डीबी से

  1. लोड सभी उपयोगकर्ताओं उपयोगकर्ताओं और उन्हें जावा में फ़िल्टर कर
  2. कई ORs और LIKE % :searchString %

विकल्प 1 के साथ एक JPQL क्वेरी लिखें:

मैं 2 विकल्प यह करने के लिए देखना प्रदर्शन के लिए अच्छा नहीं है लेकिन लिखने के लिए काफी अच्छा है।

विकल्प 2 डीबी पक्ष पर निष्पादित बीक्यूज निष्पादित किया गया है लेकिन लिखने के लिए बोझिल है।

अभी आईएम मुकदमा विकल्प 1 क्योंकि मुझे बूलियन को "yes"/"no" पर अनुवाद करने की आवश्यकता है और एक प्रोफ़ाइल enum भी है जहां मैं इसके क्षेत्र के विवरण से खोजना चाहता हूं, न कि वास्तविक enum value द्वारा।

उपयोगकर्ता इकाई में मेरे पास है एक तरीका है जिसके सभी क्षेत्रों मैं चाहता हूँ रिक्त स्थान से अलग खोजे जाने के लिए रिटर्न:

public String getSearchString(){ 
     return StringUtils.join(
       Arrays.asList(
         login, 
         firstName, 
         lastName, 
         email, 
         active ? "yes" : "no", 
         profile.getDescription()) 
       , " "); 
    } 

एक सेवा में मैं इस खोज स्ट्रिंग द्वारा DB और फिल्टर से सभी उपयोगकर्ताओं को लोड:

@Override 
    public List<User> getUsers(final String searchText) { 
     final List<User> users = getUsers(); 
     if(StringUtils.isBlank(searchText)){ 
     return users; 
     } 
     CollectionUtils.filter(users, new Predicate<User>() { 
     @Override 
     public boolean evaluate(User object) { 
      return StringUtils.containsIgnoreCase(object.getSearchString(), searchText); 
     } 
     }); 
     return users; 
    } 

जेपीक्यूएल में दूसरी तरफ मैं इस तरह के प्रश्नों के साथ समाप्त होता हूं, जो मुझे नहीं लगता कि यह कार्यक्षमता लागू करने का सबसे अच्छा और आसान तरीका है। इसके अलावा translatin बूलियन के साथ "हाँ" और "नहीं" के साथ एक समस्या है।

@Query("SELECT r FROM User r WHERE " 
     + "r.firstname LIKE '%' || :searchString || '%' " 
     + "OR r.lastname LIKE '%' || :searchString || '%' " 
     + "OR r.login LIKE '%' || :searchString || '%' " 
     + "OR r.profile.description LIKE '%' || :searchString || '%' " 
     + "OR r.active LIKE '%' || :searchString || '%' " 
     + "OR r.email LIKE '%' || :searchString || '%'") 
List<User> selectUsers(@Param("searchString")String searchString, Pageable page); 

इस समस्या का एक बेहतर समाधान है?

+1

यह हो सकता है

@PreUpdate @PrePersist void updateSearchString() { final String fullSearchString = StringUtils.join(Arrays.asList( login, firstName, lastName, email, Boolean.TRUE.equals(active) ? "tak" : "nie", profile.getDescription()), " "); this.searchString = StringUtils.substring(fullSearchString, 0, 999); } 

तब मैं LIKE साथ एक सामान्य JPQL क्वेरी हो सकता है आप जो करने की कोशिश कर रहे हैं उसके लिए बहुत भारी वजन, लेकिन आप हाइबरनेट खोजक भी देख सकते हैं एच प्रोजेक्ट (http://hibernate.org/search/documentation/getting-started/)। हाइबरनेट खोज अनुक्रमणिका फ़ील्ड जिन्हें आप टेक्स्ट खोज करना चाहते हैं। फिर एक क्वेरी फॉर्म लेती है: qb.keyword()। OnFields (<फ़ील्ड की सूची>)। मिलान () .createQuery(); –

+1

स्पष्ट रूप से जेपीक्यूएल उद्धरण मान्य जेपीक्यूएल मान्य नहीं है। कोई || ऑपरेटर, CONCAT का उपयोग करें। –

उत्तर

2

प्रत्येक persist पर खोज स्ट्रिंग को सहेजकर और डीबी को अपडेट करके इसे हल किया।

@Column(name = "SEARCH_STRING", length = 1000) 
    private String searchString; 

भंडारण सस्ती है, डीबी पर भूमि के ऊपर है कि बड़ा नहीं है: पहले searchString के लिए एक स्तंभ बनाया।

तब अद्यतन पर बचत और जारी रहती है:

SELECT u FROM User u WHERE u.searchString LIKE '%' || :text || '%' 

या Query By Example का उपयोग कर:

ExampleMatcher matcher = ExampleMatcher.matching(). 
      withMatcher("searchString", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.CONTAINING).ignoreCase()); 
0

ठीक है, ज्यादातर मामलों के लिए, विकल्प 1 वास्तव में एक विकल्प नहीं है। यदि आपका आवेदन रजिस्टरों से बड़ा हो जाता है तो स्मृति और प्रदर्शन समस्याएं कुछ समय बाद आपको प्रभावित कर सकती हैं। मैं तुम्हें भरोसा देता हूं।

मुझे विकल्प 2 में कोई समस्या नहीं दिखाई दे रही है। निष्पादक नहीं है लेकिन समझना आसान है।

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

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