// Create results for trec_val evaluation private void AutoParsing_Click(object sender, EventArgs e) { saveInfoDialog.Filter = "Text File|*.txt"; saveInfoDialog.Title = "Save Text File"; stopwatch = new Stopwatch(); string totalSearchTime = null; // Check if it has already indexed if (indexingState == true) { if (saveInfoDialog.ShowDialog() == DialogResult.OK) { int index = 0; string documentID = null; // Get speficied file path and topic ID string path = saveInfoDialog.FileName; List <string> infoID = new List <string>(); List <string> infoNeeds = new List <string>(); // Preprocess the document string[] delimeters = { ".I ", ".D" }; string[] infoTokens = Resource.cran_information_needs.Split(delimeters, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < infoTokens.Length; i++) { if (i % 2 == 0) { infoID.Add(infoTokens[i]); } else { infoNeeds.Add(infoTokens[i]); } } // Print out the results across each information needs foreach (var infoNeed in infoNeeds) { int rank = 0; searching = new SearchingClass(); stopwatch.Start(); TopDocs infoResults = searching.SearchIndex(IndexingClass.luceneIndexDirectory, IndexingClass.analyzer, infoNeed, PhraseFormCheckbox.Checked, StemCheckBox.Checked, QueryExpansionCheckBox.Checked); stopwatch.Stop(); searching.ClearnUpSearcher(); // Check whether the specified file is already exists or not if (File.Exists(path)) { // Append new results to existing file if it is true using (StreamWriter stwriter = File.AppendText(path)) { foreach (ScoreDoc scorDoc in infoResults.ScoreDocs) { rank++; // Use searcher to acquire doucment ID using (IndexSearcher searcher = new IndexSearcher(IndexingClass.luceneIndexDirectory)) { documentID = searcher.Doc(scorDoc.Doc).Get(IndexingClass.FieldDOC_ID).ToString(); documentID = documentID.Split(new[] { '\n' })[0]; } // Write to the file stwriter.WriteLine("{0,-4} {1,-4} {2,-7} {3,-5} {4,-11} {5}", infoID[index].Substring(0, 3), "Q0", documentID, rank, scorDoc.Score, "n9843329_n9861718_n5767032_HelloWorldTeam"); } } } else { using (StreamWriter stwriter = new StreamWriter(File.Create(path))) { foreach (ScoreDoc scorDoc in infoResults.ScoreDocs) { rank++; using (IndexSearcher searcher = new IndexSearcher(IndexingClass.luceneIndexDirectory)) { documentID = searcher.Doc(scorDoc.Doc).Get(IndexingClass.FieldDOC_ID).ToString(); documentID = documentID.Split(new[] { '\n' })[0]; } stwriter.WriteLine("{0,-4} {1,-4} {2,-7} {3,-5} {4,-11} {5}", infoID[index].Substring(0, 3), "Q0", documentID, rank, scorDoc.Score, "n9843329_n9861718_n5767032_HelloWorldTeam"); } } } index++; } } } else { MessageBox.Show("You need to do indexing before generating the results"); } MessageBox.Show(stopwatch.Elapsed.ToString(), "Searching time"); }
//ищем услугу в индексе. что ищем (queryString) и в каком поле (Field) //TODO: переделать на поиск по множеству полей и выдачу нужных полей (передача SearchObject?) public List <XSearchObjJSON> Search(string queryString) { lock (searchLock) { IndexReader reader = IndexReader.Open(_catalogPath, true); //ReadOnly = true для производительности IndexSearcher searcher = null; try { //создаем список JSON объектов для сериализации List <XSearchObjJSON> xsearchObjList = new List <XSearchObjJSON>(); //Создадим IndexSearcher searcher = new IndexSearcher(reader); //Если в строке поиска меньше символов чем нужно, то кидаем сообщение в UI if (queryString.Length < minSymbPerSearch) { //придумать коды ошибок, чтобы уже на UI возвращать ошибку в нужном языке langData.lbl_search_not_found_message[lang] xsearchObjList.Add(new XSearchObjJSON("error001")); //удаляем Searcher и Reader; searcher.Dispose(); reader.Dispose(); return(xsearchObjList); } // Строим Query объект //**************************************************************************************** // Внимание!!! добавляем "*" согласно синтаксу Lucene ищет вхождения по всему индексированномоу тексту //**************************************************************************************** Regex lucenePattern = new Regex(LUCENE_ESCAPE_CHARS); string escapedQuery = queryString; //escapedQuery = lucenePattern.Replace(queryString, REPLACEMENT_STRING); //string escapedQuery1 = Regex.Replace(escapedQuery, @"\\", @"\"); //escapedQuery = Helper.RemoveDuplicateCharsFast(escapedQuery, '\\'); QueryParser parser = new QueryParser(Version.LUCENE_30, SearchField, analyzer); //BooleanQuery q = new BooleanQuery(); //разершаем поиск вида "*кредит" parser.AllowLeadingWildcard = true; /*устанавливаем поиск вхождения по всем термам term1 AND term2 AND... QueryParser.AND_OPERATOR * (исправляет кейс ниже) * Шаги воспроизведения: * 1. Ввести «моя креди» и нажать на кнопку Далее * Актуальный результат: * Найдена только услуга «Моя кредитная история» * Ожидаемый результат: * Найдены услуги имеющие либо слово моя либо слово креди */ parser.DefaultOperator = QueryParser.AND_OPERATOR; /* но если требуется вхождение по "инн 1" всех "инн 102, инн 101233" * то придется убрать либо ставить QueryParser.OR_OPERATOR */ //parser.DefaultOperator = QueryParser.OR_OPERATOR; //Query query = parser.Parse(QueryParser.Escape(queryString)+"*"); Query query = parser.Parse(escapedQuery + '*'); //Query query = parser.Parse(queryString); // Search for the query TopScoreDocCollector collector = TopScoreDocCollector.Create(maxHitsPerSearch, false); searcher.Search(query, collector); ScoreDoc[] hits = collector.TopDocs().ScoreDocs; int hitCount = hits.Length; if (hitCount == 0) { //Console.WriteLine("Совпадений для \"" + queryString + "\" не найдено"); //пример сообщения для ui //xsearchObjList.Add(new XSearchObjJSON("Услуги не найдены")); } else { //Console.WriteLine("Совпадений для \"" + queryString + "\" найдено:"); // Ищем по всем документам в индексе for (int i = 0; i < hitCount; i++) { ScoreDoc scoreDoc = hits[i]; int docId = scoreDoc.Doc; //float docScore = scoreDoc.Score; Document doc = searcher.Doc(docId); //вытаскиваем все поля и создаем объект для сериализации string logo = (doc.Get(Helper.GETNAME(new { read_xsobj_field.logo })) == String.Empty || doc.Get(Helper.GETNAME(new { read_xsobj_field.logo })) == null) ? String.Empty : doc.Get(Helper.GETNAME(new { read_xsobj_field.logo })); if (!Path.HasExtension(logo)) { logo = logo + imagesExtention; } XSearchObjJSON temp = new XSearchObjJSON(doc.Get(Helper.GETNAME(new { read_xsobj_field.id_service })), doc.Get(Helper.GETNAME(new { read_xsobj_field.alias })), doc.Get(Helper.GETNAME(new { read_xsobj_field.scen_alias })), doc.Get(Helper.GETNAME(new { read_xsobj_field.name_service })), logo); //ничего не пишем в сообщения temp.message = string.Empty; //добавляем объекты удачного поиска для сериализации xsearchObjList.Add(temp); } } //удаляем Searcher и Reader; searcher.Dispose(); reader.Dispose(); //return json; return(xsearchObjList); } catch (Exception ex) { if (ex is ParseException || ex is IOException || ex is NullReferenceException) { //удаляем Searcher и Reader??? if (searcher != null) { searcher.Dispose(); } reader.Dispose(); //сообщаем об ошибках наружу } throw; } } }
private void SaveDocumentButton_Click(object sender, EventArgs e) { // Restrict the storing file type saveFileDialog.Filter = "Text File|*.txt"; saveFileDialog.Title = "Save Text File"; // Disable overwrite alert saveFileDialog.OverwritePrompt = false; // Check if there is any topic input if (!(topicEnter.Text == "")) { if (saveFileDialog.ShowDialog() == DialogResult.OK) { int rank = 0; string documentID = null; // Get speficied file path and topic ID string path = saveFileDialog.FileName; string topicID = topicEnter.Text; // Check whether the specified file already exists or not if (File.Exists(path)) { // Append new results to existing file if it is true using (StreamWriter stwriter = File.AppendText(path)) { foreach (ScoreDoc scorDoc in topDocResults.ScoreDocs) { rank++; // Use searcher to acquire doucment ID using (IndexSearcher searcher = new IndexSearcher(IndexingClass.luceneIndexDirectory)) { documentID = searcher.Doc(scorDoc.Doc).Get(IndexingClass.FieldDOC_ID).ToString(); documentID = documentID.Split(new[] { '\n' })[0]; } // Write to the file stwriter.WriteLine("{0,-4} {1,-4} {2,-7} {3,-5} {4,-11} {5}", topicID, "Q0", documentID, rank, scorDoc.Score, "n9843329_n9861718_n5767032_HelloWorldTeam"); } } } else { // Create new file if it is false using (StreamWriter stwriter = new StreamWriter(File.Create(path))) { foreach (ScoreDoc scorDoc in topDocResults.ScoreDocs) { rank++; using (IndexSearcher searcher = new IndexSearcher(IndexingClass.luceneIndexDirectory)) { documentID = searcher.Doc(scorDoc.Doc).Get(IndexingClass.FieldDOC_ID).ToString(); documentID = documentID.Split(new[] { '\n' })[0]; } stwriter.WriteLine("{0,-4} {1,-4} {2,-7} {3,-5} {4,-11} {5}", topicID, "Q0", documentID, rank, scorDoc.Score, "n9843329_n9861718_n5767032_HelloWorldTeam"); } } } } this.Hide(); } // Notify user if he/she did not specify topic ID else { MessageBox.Show("Please specify topic ID"); } }
//ищем в индексе услуги по alias-у и дополняем в индексе поля с незаданным scen_alias (алиас сценария) public void MergeWithScenAliasList(IEnumerable <XSearchObj> list, bool withoutMenu) { lock (searchLock) { IndexWriter catalogWriter = Initialize(ref _catalogPath, false, false); //IndexReader reader = IndexReader.Open(catalogPath, false); //ReadOnly = false IndexReader reader = catalogWriter.GetReader(); IndexSearcher searcher = new IndexSearcher(reader); //поиск по alias-у foreach (XSearchObj obj in list) { //ищем есть ли в индексе услуга с соответвующим алиасом Term aliasTerm = new Term(Helper.GETNAME(new { obj.alias }), new string(obj.alias)); Query query = new TermQuery(aliasTerm); //TODO: посмотреть все ли результаты отдает, если нет, писать свой CustomCollector (важно!!!) TopDocs docs = searcher.Search(query, maxHitsPerSearch); ScoreDoc[] hits = docs.ScoreDocs; if (docs.TotalHits > 0) { //пробегаем по результатам и for (int i = 0; i < docs.TotalHits; i++) { ScoreDoc t = hits[i]; Document doc = searcher.Doc(t.Doc); //int docId = t.Doc; try { //***********удаляем старый документ (по запросу) !!!Если есть дубли может возникнуть ошибка в цикле, обработать!!!****** catalogWriter.DeleteDocuments(query); } catch (OutOfMemoryException) { catalogWriter.Dispose(); throw; } XSearchObj temp = new XSearchObj { id_service = doc.Get(Helper.GETNAME(new { obj.id_service })).ToCharArray(), alias = doc.Get(Helper.GETNAME(new { obj.alias })).ToCharArray(), scen_alias = obj.scen_alias, name_service = doc.Get(Helper.GETNAME(new { obj.name_service })).ToCharArray(), logo = doc.Get(Helper.GETNAME(new { obj.logo })).ToCharArray(), version = doc.Get(Helper.GETNAME(new { obj.version })).ToCharArray(), search_tag = doc.Get(Helper.GETNAME(new { obj.search_tag })).ToCharArray() }; //Term scenAlias = new Term("scen_alias", obj.scen_alias.ToString()); //catalogWriter.UpdateDocument(scenAlias, doc); //добавляем обновленный (с именем сценария) catalogWriter.AddDocument(CreateDocument(ref temp)); } } } if (!withoutMenu) { //удаляем все из индекса что не содержит алиаса сценария try { Term emptyScenAlias = new Term(Helper.GETNAME(new { read_xsobj_field.scen_alias }), String.Empty); catalogWriter.DeleteDocuments(emptyScenAlias); } catch (Exception ex) { catalogWriter.Dispose(); throw ex; } } Optimize(ref catalogWriter); Dispose(ref catalogWriter); } }