2010-11-03 11 views
10

मैं लुसीन में नौसिखिया हूं, और मुझे टेक्स्ट फ़ाइल संग्रह क्वेरी करने के लिए सरल कोड बनाने में कुछ समस्याएं आ रही हैं।मैं ल्यूसीन 3.0.2 में टेक्स्ट फ़ाइलों को इंडेक्स और खोज कैसे करूं?

मैंने this example की कोशिश की, लेकिन लुसीन के नए संस्करण के साथ असंगत है।

यूडीपीएटी:This is my new code, लेकिन यह अभी तक काम नहीं करता है।

उत्तर

33

Lucene वर्गों और तरीकों को कवर करने का एक बहुत कुछ के साथ एक बहुत बड़ा विषय है की तुलना @http://lucene.apache.org/solr/ Solr पर गौर करें, और आप आम तौर पर समझ के बिना उपयोग नहीं कर सकते कम से कम कुछ बुनियादी अवधारणाएं। यदि आपको त्वरित रूप से उपलब्ध सेवा की आवश्यकता है, तो इसके बजाय Solr का उपयोग करें। यदि आपको ल्यूसीन के पूर्ण नियंत्रण की आवश्यकता है, तो पढ़ने पर जाएं। मैं कुछ मूल ल्यूसीन अवधारणाओं और कक्षाओं को कवर करूंगा, जो उनका प्रतिनिधित्व करते हैं। (स्मृति में पाठ फ़ाइलों को पढ़ने के तरीके के बारे में जानकारी के लिए, उदाहरण के लिए, this आलेख)।

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

Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_30, "English"); 

आप अलग अलग भाषाओं में सूचकांक ग्रंथों करने जा रहे हैं, और स्वचालित रूप विश्लेषक का चयन करना चाहते हैं, तो आप tika's LanguageIdentifier उपयोग कर सकते हैं।

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

Directory directory = new RAMDirectory(); // RAM index storage 
Directory directory = FSDirectory.open(new File("/path/to/index")); // disk index storage 

आप जोड़, अपडेट या दस्तावेज़ को नष्ट करना चाहते हैं, तो आप IndexWriter की जरूरत है:

IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(25000)); 

कोई भी दस्तावेज़ (आपके मामले में पाठ फ़ाइल) एक है खेतों का सेट दस्तावेज है, जो अपनी फ़ाइल के बारे में जानकारी का आयोजन करेगा बनाने के लिए, इस का उपयोग करें:

Document doc = new Document(); 
String title = nameOfYourFile; 
doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED)); // adding title field 
String content = contentsOfYourFile; 
doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED)); // adding content field 
writer.addDocument(doc); // writing new document to the index 

Field निर्माता क्षेत्र का नाम लेता है, यह पाठ है और कम से कम 2 अधिक पैरामीटर। पहला एक ध्वज है, जो दिखाता है कि लुसीन को इस क्षेत्र को स्टोर करना होगा या नहीं। यदि यह Field.Store.YES के बराबर है तो आपको अपने सभी टेक्स्ट को इंडेक्स से वापस लेने की संभावना होगी, अन्यथा इसके बारे में केवल अनुक्रमणिका जानकारी संग्रहीत की जाएगी।
दूसरा पैरामीटर दिखाता है कि ल्यूसीन को इस क्षेत्र को इंडेक्स करना चाहिए या नहीं। किसी भी क्षेत्र के लिए Field.Index.ANALYZED का उपयोग करें जिस पर आप खोज रहे हैं।
आम तौर पर, आप ऊपर दिखाए गए दोनों पैरामीटर का उपयोग करते हैं।

मत भूलना बंद करने के लिए अपने IndexWriter के बाद काम किया जाता है:

writer.close(); 

खोज थोड़ा मुश्किल है। आप कई वर्गों की आवश्यकता होगी: Query और QueryParser परिणाम स्टोर करने के लिए स्ट्रिंग, वास्तविक खोज के लिए IndexSearcher, TopScoreDocCollector से Lucene क्वेरी बनाने के लिए (यह एक पैरामीटर के रूप IndexSearcher में भेजा जाता है) और ScoreDoc परिणामों के माध्यम से पुनरावृति करने के लिए। अगला टुकड़ा दिखाता है कि कैसे यह सब बना है: QueryParser निर्माता को

IndexSearcher searcher = new IndexSearcher(directory); 
QueryParser parser = new QueryParser(Version.LUCENE_30, "content", analyzer); 
Query query = parser.parse("terms to search"); 
TopScoreDocCollector collector = TopScoreDocCollector.create(HOW_MANY_RESULTS_TO_COLLECT, true); 
searcher.search(query, collector); 

ScoreDoc[] hits = collector.topDocs().scoreDocs; 
// `i` is just a number of document in Lucene. Note, that this number may change after document deletion 
for (int i = 0; i < hits.length; i++) { 
    Document hitDoc = searcher.doc(hits[i].doc); // getting actual document 
    System.out.println("Title: " + hitDoc.get("title")); 
    System.out.println("Content: " + hitDoc.get("content")); 
    System.out.println(); 
} 

नोट दूसरा तर्क - यह डिफ़ॉल्ट क्षेत्र है, अर्थात क्षेत्र है कि खोज की जाएगी, अगर कोई क्वालीफायर दिया गया था है। उदाहरण के लिए, यदि आपकी क्वेरी है "शीर्षक: शब्द", Lucene एक शब्द "शब्द" के लिए क्षेत्र के सभी दस्तावेज़ों की "शीर्षक" में खोज करेंगे, लेकिन अगर आपकी क्वेरी बस "शब्द" है अगर इस मामले में, डिफ़ॉल्ट क्षेत्र में खोज करेंगे - "सामग्री"। अधिक जानकारी के लिए Lucene Query Syntax देखें।
QueryParser भी एक अंतिम तर्क के रूप में विश्लेषक लेता है। यह वही विश्लेषक होना चाहिए जैसा कि आप अपने पाठ को इंडेक्स करते थे।

आखिरी बात आपको पता होना चाहिए एक TopScoreDocCollector.create पहले पैरामीटर है। यह केवल एक संख्या है जो दर्शाती है कि आप कितने परिणाम एकत्र करना चाहते हैं। उदाहरण के लिए, अगर यह बराबर 100 है, Lucene सिर्फ पहले (स्कोर) के द्वारा 100 परिणाम को इकट्ठा करने और बाकी को छोड़ देंगे। यह सिर्फ अनुकूलन के एक अधिनियम है - आप सबसे अच्छा परिणाम एकत्रित करते हैं, और यदि आप इसे से संतुष्ट नहीं हैं, तो आप एक बड़ी संख्या के साथ दोबारा खोज।

अंत में, भूल नहीं नहीं ढीला सिस्टम संसाधनों को खोजकर्ता और निर्देशिका बंद करने के लिए:

searcher.close(); 
directory.close(); 

संपादित करें: इसके अलावा Lucene 3.0 sources से IndexFiles demo class देखते हैं।

+0

मुझे यह http://pastebin.com/HqrbBPtp करने की कोशिश की गई है, लेकिन सफलता के बिना ... – celsowm

+0

लाइन 80 में आपके पास है: 'QueryParser parser = new QueryParser (Version.LUCENE_30, "कंप्यूटर", विश्लेषक); 'यानी आप "कंप्यूटर" पर दूसरा पैरामीटर (डिफ़ॉल्ट फ़ील्ड) सेट करते हैं, और फिर आप क्वालीफायर के बिना खोज करते हैं। Lucene डिफ़ॉल्ट _field_ "कंप्यूटर" का उपयोग करने के _term_ "कंप्यूटर" खोजने की कोशिश करता है, और के बाद से अपने दस्तावेज़ में इस तरह के क्षेत्र नहीं है, Lucene विफल रहता है। 'QueryParser पार्सर = नया क्वेरीपर्सर (संस्करण। LUCENE_30, "सामग्री", विश्लेषक) का उपयोग करें; या योग्यता के साथ खोजें:' क्वेरी क्वेरी = parser.parse ("सामग्री: कंप्यूटर"); '। – ffriend

1

मैं सुझाव है कि आप बल्कि Lucene एपीआई के साथ काम करने

+0

या http://elasticsearch.org – Andy

3
package org.test; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 


import org.apache.lucene.queryParser.*; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.ScoreDoc; 
import org.apache.lucene.search.TopScoreDocCollector; 
import org.apache.lucene.store.Directory; 
import org.apache.lucene.store.FSDirectory; 
import org.apache.lucene.store.LockObtainFailedException; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.index.CorruptIndexException; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.store.RAMDirectory; 
import org.apache.lucene.util.Version; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 

public class LuceneSimple { 

private static void addDoc(IndexWriter w, String value) throws IOException { 
    Document doc = new Document(); 
    doc.add(new Field("title", value, Field.Store.YES, Field.Index.ANALYZED)); 
    w.addDocument(doc); 
} 



public static void main(String[] args) throws CorruptIndexException, LockObtainFailedException, IOException, ParseException { 

    File dir = new File("F:/tmp/dir"); 

    StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_30); 

    Directory index = new RAMDirectory(); 
    //Directory index = FSDirectory.open(new File("lucDirHello")); 


    IndexWriter w = new IndexWriter(index, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); 

    w.setRAMBufferSizeMB(200); 

    System.out.println(index.getClass() + " RamBuff:" + w.getRAMBufferSizeMB()); 

    addDoc(w, "Lucene in Action"); 
    addDoc(w, "Lucene for Dummies"); 
    addDoc(w, "Managing Gigabytes"); 
    addDoc(w, "The Art of Computer Science"); 
    addDoc(w, "Computer Science ! what is that ?"); 


    Long N = 0l; 

    for(File f : dir.listFiles()){ 
     BufferedReader br = new BufferedReader(new FileReader(f)); 
     String line = null; 
     while((line = br.readLine()) != null){ 
     if(line.length() < 140) continue;  
     addDoc(w, line); 
     ++N; 
     } 
     br.close(); 
    } 

    w.close(); 

    // 2. query 
    String querystr = "Computer"; 

    Query q = new QueryParser(Version.LUCENE_30, "title", analyzer).parse(querystr); 


    //search 
    int hitsPerPage = 10; 

    IndexSearcher searcher = new IndexSearcher(index, true); 

    TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); 

    searcher.search(q, collector); 

    ScoreDoc[] hits = collector.topDocs().scoreDocs; 

    System.out.println("Found " + hits.length + " hits."); 
    for(int i=0;i<hits.length;++i) { 
     int docId = hits[i].doc; 
     Document d = searcher.doc(docId); 
     System.out.println((i + 1) + ". " + d.get("title")); 
    } 


    searcher.close(); 

} 

} 
+0

आप "फ़ाइल डीआईआर" वैरिएबल को उस निर्देशिका में सेट कर सकते हैं जिसे आपको इंडेक्स करने की आवश्यकता है। – smartnut007

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