2013-02-25 18 views
5

में सूचकांक और searchnumbers करना मेरी 3.6 कोड में मैं अपने सूचकांक करने के लिए संख्यात्मक फ़ील्ड जोड़ने था इस प्रकार है:कैसे आप Lucene 4.1

public void addNumericField(IndexField field, Integer value) { 
     addField(field, NumericUtils.intToPrefixCoded(value)); 
    } 

लेकिन अब आप इसे एक BytesRef तर्क पारित करने के लिए की जरूरत है, और इसकी पूरी तरह से स्पष्ट नहीं है क्या आप मूल्य अगले तो बजाय मैं इसे (प्रगति में काम)

public void addNumericField(IndexField field, Integer value) { 
     FieldType ft = new FieldType(); 
     ft.setStored(true); 
     ft.setIndexed(true); 
     ft.setNumericType(FieldType.NumericType.INT); 
     doc.add(new IntField(field.getName(), value, ft)); 
    } 

जो लग रहा था neater

3.6 में मैं भी यह काम करने के लिए queryparser ओवरराइड करने के लिए जोड़ने के लिए बदल दिया है के साथ क्या करना है सांख्यिक श्रेणी खोजों के लिए,

package org.musicbrainz.search.servlet; 

import org.apache.lucene.index.Term; 
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.TermQuery; 
import org.apache.lucene.search.TermRangeQuery; 
import org.apache.lucene.util.NumericUtils; 
import org.musicbrainz.search.LuceneVersion; 
import org.musicbrainz.search.index.LabelIndexField; 
import org.musicbrainz.search.servlet.mmd1.LabelType; 

public class LabelQueryParser extends MultiFieldQueryParser { 

    public LabelQueryParser(java.lang.String[] strings, org.apache.lucene.analysis.Analyzer analyzer) 
    { 
     super(LuceneVersion.LUCENE_VERSION, strings, analyzer); 
    } 

    protected Query newTermQuery(Term term) { 

     if(
       (term.field() == LabelIndexField.CODE.getName()) 
       ){ 
      try { 
       int number = Integer.parseInt(term.text()); 
       TermQuery tq = new TermQuery(new Term(term.field(), NumericUtils.intToPrefixCoded(number))); 
       return tq; 
      } 
      catch (NumberFormatException nfe) { 
       //If not provided numeric argument just leave as is, 
       //won't give matches 
       return super.newTermQuery(term); 
      } 
     } else { 
      return super.newTermQuery(term); 

     } 
    } 

    /** 
    * 
    * Convert Numeric Fields 
    * 
    * @param field 
    * @param part1 
    * @param part2 
    * @param inclusive 
    * @return 
    */ 
    @Override 
    public Query newRangeQuery(String field, 
           String part1, 
           String part2, 
           boolean inclusive) { 

     if (
       (field.equals(LabelIndexField.CODE.getName())) 
      ) 
     { 
      part1 = NumericUtils.intToPrefixCoded(Integer.parseInt(part1)); 
      part2 = NumericUtils.intToPrefixCoded(Integer.parseInt(part2)); 
     } 
     TermRangeQuery query = (TermRangeQuery) 
       super.newRangeQuery(field, part1, part2,inclusive); 
     return query; 
    } 

} 

तो मैं यह सब पता लगाना मैं इसे अब और की जरूरत नहीं लिया, लेकिन दुर्भाग्य से इस IntField पर कोई प्रश्नों अब काम कर रहे हैं।

आगे पढ़ना ऐसा लगता है कि इंटीफील्ड का उपयोग केवल श्रेणी प्रश्नों के लिए किया जाता है, इसलिए मुझे नहीं पता कि आप केवल मिलान प्रश्नों के लिए कैसे हैं, और क्या NumericRangeQuery क्लासिक क्वेरी पार्सर के साथ comptable है जिसका मैं उपयोग कर रहा हूं।

तो मैं तो इनकोडिंग स्ट्रिंग

public void addNumericField(IndexField field, Integer value) { 

    FieldType fieldType = new FieldType(); 
    fieldType.setStored(true); 
    fieldType.setIndexed(true); 
    BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); 
    NumericUtils.intToPrefixCoded(value, 0, bytes); 
    doc.add(new Field(field.getName(),bytes, fieldType)); 
} 

के रूप में मेरे संख्यात्मक मान जोड़ने की कोशिश कर में वापस चला गया लेकिन रनटाइम पर अब मैं त्रुटि मिल रही है!

java.lang.IllegalArgumentException: Fields with BytesRef values cannot be indexed 

लेकिन मैं सूचकांक क्षेत्र की जरूरत है, तो मैं सूचकांक संख्यात्मक फ़ील्ड जैसे मैं 3.6 में क्या इसलिए मैं उन्हें खोज कर सकते हैं कर सकते हैं कि कृपया।

उत्तर

1

बस उपयुक्त क्षेत्र का उपयोग इस प्रकार इंडेक्स से बाहर मूल intgeral मूल्य मिल सकता है। उदाहरण IntField, LongField, आदि

के लिए उदाहरण http://lucene.apache.org/core/4_1_0/core/org/apache/lucene/document/IntField.html

के लिए देखें इन क्षेत्रों की क्वेरी के लिए, Lucene LongField exact search with Query

+0

लेकिन यदि इंफिल्ड का उपयोग करना है तो मैं ऐसे क्षेत्रों को खोजने के लिए क्वेरीपर्सर का विस्तार कैसे करूं? –

+1

मूल्य संख्या में एक पूर्णांक में उपयुक्त NumericRangeQuery लौटें। इसलिए, TermQuery को वापस करने के बजाय, यदि आवश्यक हो तो newTermQuery विधि में NumericRangeQuery वापस करें। – RobAu

0

तो मुझे यह काम मिल गया है, चाहे यह उन चीज़ों को करने का सबसे अच्छा तरीका है जिन्हें मैं नहीं जानता।

  1. स्ट्रिंग के रूप में सूचकांक के लिए नंबर जोड़ रहा है

    FieldType fieldType = new FieldType(); 
    fieldType.setStored(true); 
    fieldType.setIndexed(true); 
    BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); 
    NumericUtils.intToPrefixCoded(value, 0, bytes); 
    doc.add(new Field(field.getName(),bytes.utf8ToString(), fieldType)); 
    
  2. QueryParser, बहर सकता उपयोग ==

    protected Query newTermQuery(Term term) 
    { 
    
        if (term.field().equals(LabelIndexField.CODE.getName())) 
        { 
         try 
         { 
    
          int number = Integer.parseInt(term.text()); 
          BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); 
          NumericUtils.intToPrefixCoded(number, 0, bytes); 
          TermQuery tq = new TermQuery(new Term(term.field(), bytes.utf8ToString())); 
          return tq; 
         } 
         catch (NumberFormatException nfe) 
         { 
          //If not provided numeric argument just leave as is, won't give matches 
          return super.newTermQuery(term); 
         } 
        } 
        else 
        { 
         return super.newTermQuery(term); 
    
        } 
    } 
    
  3. इसके अलावा के हस्ताक्षर, बराबर() का उपयोग कर FIELDNAME जाँच करने की जरूरत है कि पहले newRangeQuery() बदल गया है, अतिरिक्त पैरामीटर अंत समावेशी

    public Query newRangeQuery(String field, 
              String part1, 
              String part2, 
              boolean startInclusive, 
              boolean endInclusive) 
    { 
        if (
          (field.equals(LabelIndexField.CODE.getName())) 
          ) 
        { 
         BytesRef bytes1 = new BytesRef(NumericUtils.BUF_SIZE_INT); 
         BytesRef bytes2 = new BytesRef(NumericUtils.BUF_SIZE_INT); 
         NumericUtils.intToPrefixCoded(Integer.parseInt(part1), 0, bytes1); 
         NumericUtils.intToPrefixCoded(Integer.parseInt(part2), 0, bytes2); 
         part1 = bytes1.utf8ToString(); 
         part2 = bytes2.utf8ToString(); 
        } 
        TermRangeQuery query = (TermRangeQuery) 
          super.newRangeQuery(field, part1, part2, startInclusive, endInclusive); 
        return query; 
    
    } 
    
  4. आप के रूप

    NumericUtils.prefixCodedToInt(new BytesRef(code)) 
    
2

बस एक सिर ऊपर, कैसे Lucene 4 का उपयोग यह करने के लिए पर देखते हैं।7:

जब अनुक्रमण मैं सिर्फ folows के रूप में कार्य करें:

document.add(new IntField("int_field", int_value, Field.Store.YES)); 

और खोज के लिए:

public class MyQueryParser extends QueryParser { 

public MyQueryParser(Version matchVersion, String field, Analyzer anlayzer) { 
    super(matchVersion, field, anlayzer); 
} 

@Override 
protected Query getRangeQuery(String field, String part1, String part2, boolean startInclusive, boolean endInclusive) throws ParseException { 
    if ("int_field".equals(field)) { 
     return NumericRangeQuery.newIntRange(field, Integer.parseInt(part1), Integer.parseInt(part2), startInclusive, endInclusive); 
    } else { 
     return super.getRangeQuery(field, part1, part2, startInclusive, endInclusive); 
    } 
} 

@Override 
protected Query newTermQuery(Term term) 
{ 
    if ("int_field".equals(term.field())) { 
     try { 
      int number = Integer.parseInt(term.text()); 
      BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); 
      NumericUtils.intToPrefixCoded(number, 0, bytes); 
      TermQuery tq = new TermQuery(new Term(term.field(), bytes.utf8ToString())); 
      return tq; 
     } catch (NumberFormatException nfe) { 
      //If not provided numeric argument just leave as is, won't give matches 
      return super.newTermQuery(term); 
     } 
    } else { 
     return super.newTermQuery(term); 
    } 
} 

}

इस तरह करने से,

int_field: 1 
int_field: [1 TO 5] 
तरह querys

अपेक्षा के अनुसार काम करते हैं।

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