2009-01-24 17 views
11

मैं Lucene.NET (v2.0) का उपयोग कर विजुअल बेसिक 9 (VS2008) में डेस्कटॉप खोज इंजन विकसित कर रहा हूं।Lucene.NET अनुक्रमणिका को कैसे अपडेट करें?

मैं अगर मैं एक ही दस्तावेज़ फ़ोल्डर (फ़ाइलें अनुक्रमित करने के लिए) का चयन IndexWriter प्रारंभ करने में

Private writer As IndexWriter 

writer = New IndexWriter(indexDirectory, New StandardAnalyzer(), False) 

writer.SetUseCompoundFile(True) 

दो बार, जो दस्तावेज़ फ़ोल्डर में प्रत्येक फ़ाइल के लिए दो अलग-अलग प्रविष्टियों में बनाए जाते हैं निम्नलिखित कोड का उपयोग सूचकांक।

मैं चाहता हूं कि इंडेक्सवाइटर किसी भी फाइल को त्यागें जो पहले से ही इंडेक्स में मौजूद है।

यह सुनिश्चित करने के लिए मुझे क्या करना चाहिए?

+0

आप स्क्रैच से सूचकांक हर बार के पुनर्निर्माण के लिए कोशिश कर रहे हैं, या आप सूचकांक में विशिष्ट प्रविष्टियों अद्यतन करने के लिए कोशिश कर रहे हैं? कृपया अपने प्रश्न को स्पष्ट करें। – itsadok

उत्तर

4

एक ल्यूसीन इंडेक्स को अपडेट करने के लिए आपको पुरानी प्रविष्टि को हटाने और नई प्रविष्टि में लिखने की आवश्यकता है। इसलिए आपको वर्तमान आइटम ढूंढने के लिए इंडेक्स रीडर का उपयोग करने की आवश्यकता है, इसे हटाने के लिए लेखक का उपयोग करें और फिर अपना नया आइटम जोड़ें। यह कई प्रविष्टियों के लिए भी सच होगा जो मुझे लगता है कि आप क्या करने की कोशिश कर रहे हैं। बस सभी प्रविष्टियों को ढूंढें, उन्हें सभी हटाएं और फिर नई प्रविष्टियों में लिखें।

+0

क्या आप मुझे ऐसे डेमो पर इंगित कर सकते हैं जो इंडेक्स अपडेट करने के लिए इंडेक्स रीडर (वर्तमान आइटम ढूंढने के लिए) का उपयोग दिखाता है? – user57175

+0

ऐसा लगता है कि जब मैं पुनर्निर्माण करते समय खोज – JsonStatham

5

आप सूचकांक में सभी सामग्री हटा सकते हैं और इसे फिर से भरना चाहते हैं, तो आप इस बयान का इस्तेमाल कर सकते

writer = New IndexWriter(indexDirectory, New StandardAnalyzer(), True) 

IndexWriter constructor के अंतिम पैरामीटर निर्धारित करता है कि एक नया सूचकांक बनाया जाता है, या एक है कि क्या मौजूदा नए दस्तावेजों को जोड़ने के लिए सूचकांक खोला गया है।

+1

को समाशोधन सूचकांक के सबसे सरल उत्तर को पुनः सबमिट करता हूं, तो thx – jcvandan

19

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

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

int patientID = 12; 
IndexReader indexReader = IndexReader.Open(indexDirectory); 
indexReader.DeleteDocuments(new Term("patient_id", patientID)); 

तो फिर तुम रोगी रिकॉर्ड फिर से IndexWriter का एक उदाहरण के साथ जोड़ सकते हैं। मैंने इस आलेख http://www.codeproject.com/KB/library/IntroducingLucene.aspx से बहुत कुछ सीखा।

उम्मीद है कि इससे मदद मिलती है।

3

जब तक आप केवल कुछ ही दस्तावेजों को संशोधित नहीं कर रहे हैं (कहें, कुल में से 10% से कम) यह लगभग निश्चित रूप से तेज़ है (आपका माइलेज स्लेच से रीइंडेक्स में संग्रहीत/अनुक्रमित फ़ील्ड इत्यादि के आधार पर भिन्न हो सकता है)।

उसने कहा, मैं हमेशा एक अस्थायी निर्देशिका में अनुक्रमित करता हूं, और फिर इसे पूरा होने पर नया स्थान ले जाता है। इस तरह, सूचकांक निर्माण करते समय थोड़ा डाउनटाइम है, और यदि कुछ गलत हो जाता है तो आपके पास अभी भी एक अच्छी अनुक्रमणिका है।

11

आईडी फ़ील्ड को हटाने पर कई पुराने उदाहरण हैं। नीचे दिया गया कोड Lucene.NET 2.4 के साथ काम करेगा।

यदि आप पहले से ही इंडेक्सवाइटर का उपयोग कर रहे हैं या indexSearcher.Reader तक पहुंचने के लिए इंडेक्स रीडर खोलना जरूरी नहीं है। आप IndexWriter.DeleteDocuments (टर्म) का उपयोग कर सकते हैं, लेकिन मुश्किल हिस्सा यह सुनिश्चित कर रहा है कि आपने अपना आईडी फ़ील्ड सही जगह पर संग्रहीत किया है। सुनिश्चित करें और फील्ड.इंडेक्स का उपयोग करें।दस्तावेज़ को संग्रहीत करते समय आपके आईडी फ़ील्ड पर इंडेक्स सेटिंग के रूप में NOT_ANALYZED। यह अनुक्रमित यह tokenizing बिना क्षेत्र है, जो बहुत महत्वपूर्ण है, और अन्य Field.Index उसका कोई भी मान जब इस तरह से इस्तेमाल किया काम करेगा:

IndexWriter writer = new IndexWriter("\MyIndexFolder", new StandardAnalyzer()); 
var doc = new Document(); 
var idField = new Field("id", "MyItemId", Field.Store.YES, Field.Index.NOT_ANALYZED); 
doc.Add(idField); 
writer.AddDocument(doc); 
writer.Commit(); 

अब आप आसानी से हटा सकते हैं या एक ही लेखक का उपयोग कर दस्तावेज़ को अद्यतन कर सकते हैं:

Term idTerm = new Term("id", "MyItemId"); 
writer.DeleteDocuments(idTerm); 
writer.Commit(); 
+1

इंडेक्सवाइटर के लिए भी हस्ताक्षर अब अप्रचलित है (और लुसीन 3.0 में हटा दिया जाएगा)। सुझाए गए सीटीओ नए इंडेक्सवाइटर (निर्देशिका, विश्लेषक, maxFieldLength) और विश्लेषक के लिए होगा, फिर हस्ताक्षर अप्रचलित है। सुझाया गया एक नया मानक विश्लेषक (संस्करण) है। – autonomatt

2

एक विकल्प दस्तावेज़ को निकालने के लिए और फिर दस्तावेज़ के अद्यतन संस्करण को जोड़ने के लिए एक विकल्प है। एक व्यवस्था है जिसके द्वारा आप दस्तावेज़ आपको अवगत करवाने के ("patient_id" चाहते हैं पता लगा सकते हैं के लिए

writer.UpdateDocument(new Term("patient_id", document.Get("patient_id")), document); 

निश्चित रूप से यह आप की आवश्यकता है:

वैकल्पिक रूप से आप भी IndexWriter वर्ग की विधि UpdateDocument() का उपयोग कर सकते इस उदाहरण में)।

मेरे पास blogged more details with a more complete source code example है।

4

नीचे सूचीबद्ध विकल्प हैं, जिन्हें आवश्यकताओं के अनुसार उपयोग किया जा सकता है।

कोड स्नैप के नीचे देखें। [सी # में स्रोत कोड, कृपया इसे में तब्दील vb.net]

Lucene.Net.Documents.Document doc = ConvertToLuceneDocument(id, data); 
Lucene.Net.Store.Directory dir = Lucene.Net.Store.FSDirectory.Open(new DirectoryInfo(UpdateConfiguration.IndexTextFiles)); 
Lucene.Net.Analysis.Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29); 
Lucene.Net.Index.IndexWriter indexWriter = new Lucene.Net.Index.IndexWriter(dir, analyzer, false, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); 
Lucene.Net.Index.Term idTerm = new Lucene.Net.Index.Term("id", id); 

foreach (FileInfo file in new DirectoryInfo(UpdateConfiguration.UpdatePath).EnumerateFiles()) 
{ 
     Scenario 1: Single step update. 
       indexWriter.UpdateDocument(idTerm, doc, analyzer); 

     Scenario 2: Delete a document and then Update the document 
       indexWriter.DeleteDocuments(idTerm); 
       indexWriter.AddDocument(doc); 

     Scenario 3: Take necessary steps if a document does not exist. 

      Lucene.Net.Index.IndexReader iReader = Lucene.Net.Index.IndexReader.Open(indexWriter.GetDirectory(), true); 
      Lucene.Net.Search.IndexSearcher iSearcher = new Lucene.Net.Search.IndexSearcher(iReader); 
      int docCount = iSearcher.DocFreq(idTerm); 
      iSearcher.Close(); 
      iReader.Close(); 
      if (docCount == 0) 
      { 
        //TODO: Take necessary steps 
        //Possible Step 1: add document 
        //indexWriter.AddDocument(doc); 

        //Possible Step 2: raise the error for the unknown document 
      } 
} 
indexWriter.Optimize(); 
indexWriter.Close(); 
संबंधित मुद्दे