// The method that dispose the searcher public void ClearnUpSearcher() { searcher.Dispose(); }
//ищем услугу в индексе. что ищем (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; } } }