Laden...

Compression in Lucene.Net: Daten sind zum Zeitpunkt des Auslesens noch komprimiert

Letzter Beitrag vor 8 Jahren 1 Posts 1.112 Views
Compression in Lucene.Net: Daten sind zum Zeitpunkt des Auslesens noch komprimiert

Hallo zusammen

Ich habe seit ein einiger Zeit eine toll funktionierendes Dokumentensuch-Tool mit Dokumentenvorschau am laufen. Der Aufbau wurde ganz klassisch über Forensuche entwickelt. Nun mit 20'000 zu indexierenden Dokumenten wird der Space für die Index- und Datenfiles etwas zu gross. Da in der Aktuellen Version 3.0.3 von Lucene.Net keine direkte Compression auf FieldStore Element mehr vorhanden ist, müsste ich dies gemäss den Foren mit der CompressionTool Lib lösen. Der Einsatz für die Direkte Einbindung im Writer hat bestens geklappt (Einsparungen der Dateigrösse um 50%), da ich die Compression(binary) in die Fields gekappselt habe.

Hier der Code Snippet dazu:


 /// <summary>
        /// Indexin all File-Outputs
        /// </summary>
        /// <param name="dataToIndex"></param>
        public void BuildIndex(List<DataFromFile> dataToIndex, BackgroundWorker worker)
        {
            try
            {
                writer.MaxMergeDocs = 5000000;
                writer.MergeFactor = 10;
                worker.ReportProgress(0, "Indexing all documents...");
                worker.ReportProgress(0, dataToIndex.Count());
                var cnt = 0;
                dataToIndex.ForEach(DataFileRow =>
                {
                    var doc = new Document();
                    doc.Add(new Field("LineText", CompressionTools.CompressString(DataFileRow.LineText), Field.Store.YES));
                    doc.Add(new Field("FilePath", CompressionTools.CompressString(DataFileRow.FilePath), Field.Store.YES));
                    doc.Add(new Field("FileName", CompressionTools.CompressString(DataFileRow.FileName), Field.Store.YES));
                    doc.Add(new Field("FileTyp", CompressionTools.CompressString(DataFileRow.FileTyp), Field.Store.YES));
                    doc.Add(new Field("FileCreateDate", CompressionTools.CompressString(DataFileRow.FileCreateDate), Field.Store.YES));
                    writer.AddDocument(doc);                   
                    worker.ReportProgress(cnt++, string.Format("Indexing document: {0}", DataFileRow.FileName));
                });
                writer.Optimize(true);
                writer.Dispose();
                Thread.Sleep(500);
                luceneIndexDirectory.Dispose();
                if (!Form1.newIndexing) // Ansonsten knallt es da es kein Reader bei New Indexing gibt
                    reader.Dispose();

                if (ErrorFileList.Count() != 0)
                {
                    try
                    {
                        System.IO.File.WriteAllLines(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DocumentSearcher", "Errorfile.txt"), ErrorFileList);
                    }
                    catch
                    {
                        XtraMessageBox.Show("Error-File can't write!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

Probleme habe ich aber bei der Decompression in der Searchabfrage IndexSearcher, da die Daten bei der Abfrage noch komprimiert sind. Meine Lösung hier unten funktioniert leider nicht. Habe schon Stunden verbrachte Lösungen zu finden. Evtl. hat jemand dies schon einmal implementiert oder hat einen anderen Ansatz für mich 😉


/// <summary>
        /// Search-Query
        /// </summary>
        /// <param name="searchTerm"></param>
        /// <returns></returns>
        public List<DataFromFile> Search(string searchQuery)
        {
            int score;
            if (ConfigManager.score != 0)
                score = ConfigManager.score;
            else
                score = 1000;

            var result = new List<DataFromFile>();
            try
            {
                using (var searcher = new IndexSearcher(luceneIndexDirectory, false))
                {
                    for (int i = 0; i < searcher.MaxDoc; i++)
                    {
                        searcher.IndexReader.Document(0).GetField("FileTyp")
.SetValue(CompressionTools.Decompress(searcher.Doc(i).GetBinaryValue("FileTyp")));
                        searcher.IndexReader.Document(0).GetField("FileName")
.SetValue(CompressionTools.DecompressString(searcher.Doc(i).GetBinaryValue("FileName")));
                        searcher.IndexReader.Document(0).GetField("FilePath")
.SetValue(CompressionTools.DecompressString(searcher.Doc(i).GetBinaryValue("FilePath")));
                        searcher.IndexReader.Document(0).GetField("FileCreateDate")
.SetValue(CompressionTools.DecompressString(searcher.Doc(i).GetBinaryValue("FileCreateDate")));
                    }
                    var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
                    var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, new[] { "FileName", "LineText" }, analyzer);
                    parser.DefaultOperator = QueryParser.Operator.AND;
                    var query = parseQuery(searchQuery, parser);
                    var hits = searcher.Search(query, null, score, Sort.RELEVANCE).ScoreDocs;                  
                    result = MapLuceneToDataList(hits, searcher);
                    analyzer.Close();
                    searcher.Dispose();
                };
            }
            catch { }
            return result;
        }

PS: Ich muss noch dazu sagen ist mir klar, dass 600MB eigentlich nicht so viel Speicher ist, jedoch läuft die Applikation noch als Winform-Applikation und noch nicht als Web Services und daher kopiert das Tool die Updates des Files lokal auf jede Maschine. Daher wäre eine Kompression bis die Web Applikation läuft schon noch schön. 😁

Danke für die Unterstützung eurerseits.

Gruss Tomstrom

Hinweis von Coffeebean vor 8 Jahren

Ich habe den Titel mal versucht anzupassen. Aus dem Text entnehme ich nur, dass du "Probleme" hast beim Dekomprimieren. Wenn der Titel nicht stimmt, schreibe ihn doch bitte nochmal richtig. Danke. [Hinweis] Wie poste ich richtig? Punkt 3