2012-12-28 7 views
13

मैं दस्तावेज़ों की एक अनुक्रमणिका को लागू करने की कोशिश कर रहा हूं (डीबी पंक्तियों के साथ rougly), जहां फ़ील्ड में से एक पूर्णांक है। मैं जैसे सूचकांक करने के लिए उन्हें जोड़ रहा:लुसीन 4 में एक int फ़ील्ड कैसे खोजें?

Document doc = new Document(); 
doc.add(new StringField("ticket_number", rs.getString("ticket_number"), 
     Field.Store.YES)); 
doc.add(new IntField("ticket_id", rs.getInt("ticket_id"), 
     Field.Store.YES)); 
doc.add(new StringField("id_s", rs.getString("ticket_id"), 
     Field.Store.YES)); 
w.addDocument(doc); 

ऐसा लगता है मैं क्वेरी नहीं कर सकता ticket_id क्षेत्र है, जबकि id_s काम करता है ठीक।

दस्तावेजों में से एक (मैं पठनीयता के लिए खाली स्थान के) जोड़ा है:

Document< 
    stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<ticket_number:230114W> 
    stored<ticket_id:152> 
    stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<id_s:152>> 

तो मेरी पूर्णांक क्षेत्र संग्रहीत किया जाता है, लेकिन इंडेक्स नहीं है। यह क्वेरी अपेक्षित के रूप में काम करती है: id_s:152, जबकि यह कभी भी कुछ भी वापस नहीं करता है: ticket_id:152

मैं क्या गलत कर रहा हूं? मैं इंडेक्स में ऐसा क्षेत्र कैसे जोड़ सकता हूं और इसे खोजने योग्य बना सकता हूं?

उत्तर

7

संख्यात्मक फ़ील्ड NumericRangeQuery के साथ पूछताछ की जा सकती है। सटीक मिलान के लिए, अधिकतम और न्यूनतम बराबर मानों को सेट करें।

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

हालांकि, यह संभव है कि आईडी_एस का प्रबंधन बेहतर विकल्प हो। आईडी को आमतौर पर संख्यात्मक मानों के रूप में नहीं संभाला जाता है, बल्कि अंकों के साथ प्रदर्शित होने वाले साधारण पहचानकर्ताओं के रूप में। यदि आपको फ़ील्ड पर संख्यात्मक सॉर्टिंग या रेंज क्वेरीिंग की आवश्यकता नहीं है, तो StringField के रूप में अनुक्रमणित करना निश्चित रूप से अधिक समझ में आता है।

18

नीचे मेरे लिए काम करता है:

RAMDirectory idx = new RAMDirectory(); 
    IndexWriter writer = new IndexWriter(
      idx, 
      new IndexWriterConfig(Version.LUCENE_40, new ClassicAnalyzer(Version.LUCENE_40)) 
    ); 
    Document document = new Document(); 
    document.add(new StringField("ticket_number", "t123", Field.Store.YES)); 
    document.add(new IntField("ticket_id", 234, Field.Store.YES)); 
    document.add(new StringField("id_s", "234", Field.Store.YES)); 
    writer.addDocument(document); 
    writer.commit(); 

    IndexReader reader = DirectoryReader.open(idx); 
    IndexSearcher searcher = new IndexSearcher(reader); 

    Query q1 = new TermQuery(new Term("id_s", "234")); 
    TopDocs td1 = searcher.search(q1, 1); 
    System.out.println(td1.totalHits); // prints "1" 

    Query q2 = NumericRangeQuery.newIntRange("ticket_id", 1, 234, 234, true, true); 
    TopDocs td2 = searcher.search(q2, 1); 
    System.out.println(td2.totalHits); // prints "1" 

रूप femtoRgon ने बताया संख्यात्मक मान (देशांतर, दिनांक, तैरता, आदि) आप NumericRangeQuery है और सटीक निर्दिष्ट करने की आवश्यकता के लिए। अन्यथा लुसीन को पता नहीं है कि आप समानता को कैसे परिभाषित करना चाहते हैं।

+0

धन्यवाद आदमी, इसने मुझे बहुत मदद की। – SoluableNonagon

+0

क्या '234' डेटा का एक ही टुकड़ा इंगित करता है, यदि ऐसा है तो मुझे लगता है कि इसे एक बार स्ट्रिंग के रूप में और एक बार int के रूप में दो बार इंडेक्स में स्टोर करने का अधिकार नहीं है। –

+0

'234' विभिन्न फ़ील्ड (' टिकट_आईडी' और 'id_s') के साथ संग्रहीत है। मुझे इसके साथ कुछ भी गलत नहीं दिख रहा है। संकल्पनात्मक रूप से यह गलत हो सकता है, लेकिन इस उदाहरण का उद्देश्य केवल यह साबित करना है कि दोनों तकनीकें संभव हैं। – mindas

4

एक और जवाब इस सूत्र (तीसरी जवाब) से आता है: Lucene 4.0 IndexWriter updateDocument for Numeric Term

मूल रूप से, अगर आप इस तरह अपने पूर्णांक मान के साथ एक अवधि बनाएँ:

String field = "myfield"; 
int value = 4711; 
BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); 
NumericUtils.intToPrefixCoded(value, 0, bytes); 
Term term = new Term(field, bytes); 

तो फिर तुम खोज के लिए इस शब्द का प्रयोग कर सकते हैं, या अपनी अनुक्रमणिका को हटा/अद्यतन करना। पहले परीक्षण में, यह मेरे लिए ठीक काम किया। मैं यह नहीं बता सकता कि यह चीजों को करने का "सही" तरीका है या नहीं। मैंने IntFields को फ़िल्टर करने के लिए पहले NumericRangeFilter का उपयोग किया है, लेकिन अब मैं इस दृष्टिकोण का उपयोग करने और इसके बजाय नियमित शर्तोंफिल्टर, या TermQueries का उपयोग करने के इच्छुक हूं।

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