public IxSearchResult search(string searched) { /* Ztokenizuj fraz� */ tokenListing.reset(); tokenListing.addFromText(searched, false); uint[] tokensIds = tokenListing.getTokensIds(); Dictionary<uint, float> resultIds = new Dictionary<uint, float>(); foreach (uint tokenId in tokensIds) { /* Dla ka�dego tokenu frazy pobierz list� wyst�pie� */ Posting[] postings = invIndex.getPostingsByTokenId(tokenId); if (tokensIds.Length > 1) { /* Sta�y wsp�czynnik IDF dzielony przez wag� pierwszego dokumentu w zbiorze podwynik�w dla tego tokenu */ float IDFperMaxRank = (float)(Math.Log(documentsCount / postings.Length) + 1) / postings[0].rank; /* Scal wyniki dla tego tokenu z poprzednimi wynikami */ foreach (Posting posting in postings) if (!resultIds.ContainsKey(posting.documentId)) { resultIds[posting.documentId] = posting.rank * IDFperMaxRank; } else { resultIds[posting.documentId] += posting.rank * IDFperMaxRank; } } else { /* Nie ma poprzednich wynik�w - przepisz */ foreach (Posting posting in postings) resultIds[posting.documentId] = posting.rank; } } /* Zwracany wynik wyszukiwania */ IxSearchResult result = new IxSearchResult(); result.documents = new IxDocument[resultIds.Count]; /* Przepisz wynik ze s�ownika do tablicy, pierwsze sortowanie wg ID dokumentu: wi�ksze szanse na szybszy odczyt tytu��w */ IEnumerator<KeyValuePair<uint, float>> resultEnumerator = resultIds.OrderByDescending<KeyValuePair<uint, float>, float>(key => key.Key).GetEnumerator(); ProgressReport progress; if (IxSettings.consoleDebug) { Console.WriteLine("Rewriting result documents' ids and reading titles..."); progress = new ProgressReport(resultIds.Count, 5); } int index = 0; /* Przepisz wyniki, pobieraj�c nazwy dokument�w */ while (resultEnumerator.MoveNext()) { result.documents[index] = documentsIndex.getDocumentById(resultEnumerator.Current.Key); result.documents[index].Id = resultEnumerator.Current.Key; result.documents[index++].rank = resultEnumerator.Current.Value; if (IxSettings.consoleDebug) progress.progressOne(); } progress.done(); /* Teraz posortuj wg malej�cych ocen */ Array.Sort<IxDocument>( result.documents, delegate(IxDocument firstDocument, IxDocument nextDocument) { return nextDocument.rank.CompareTo(firstDocument.rank); } ); return result; }
public IxSearchResult Search(string phrases) { IxSearchResult result = new IxSearchResult(); List<IxPhraseAndIxSearchResult> phrasesAndDocuments = new List<IxPhraseAndIxSearchResult>(); //przygotuj listę obiektów IxPhrase na podstawie string'a List<IxPhrase> ixPhrases = GetIxPhrasesFromString(phrases); //dla tekstu każdej frazy wyszukujemy dokumenty, w których występuje foreach(var ixPhrase in ixPhrases) { IxPhraseAndIxSearchResult phraseAndDocuments = new IxPhraseAndIxSearchResult(); phraseAndDocuments.Phrase = ixPhrase; phraseAndDocuments.SearchResult = _searchEngine.search(ixPhrase.Text); phrasesAndDocuments.Add(phraseAndDocuments); } //teraz na podstawie operatorów poszczególnych fraz (AND, OR, NOT) odpowiednio //łączymy zbiory dokumentów w jeden List<IxDocument> documents = new List<IxDocument>(); foreach (var phrase in phrasesAndDocuments) { if (phrase.Phrase.Type == IxPhraseType.First) { //dodajemy bezwarunkowo wszystkie dokumenty documents.AddRange(phrase.SearchResult.documents); } else if (phrase.Phrase.Type == IxPhraseType.And) { //usuwamy wszystkie dokumenty, których nie ma w zbiorze dokumentów tej frazy List<IxDocument> newDocuments = new List<IxDocument>(); foreach (var document in documents) { IxDocument temp = phrase.SearchResult.documents.Where(x => x.title == document.title).FirstOrDefault(); if (temp != null) { newDocuments.Add(document); } } documents = newDocuments; } else if (phrase.Phrase.Type == IxPhraseType.Or) { //dodajemy wszystkie nowe dokumenty foreach (var document in phrase.SearchResult.documents) { IxDocument temp = documents.Where(x => x.title == document.title).FirstOrDefault(); if (temp == null) { documents.Add(document); } } } else if (phrase.Phrase.Type == IxPhraseType.Not) { //usuwamy wszystkie dokumenty, które są w zbiorze List<IxDocument> newDocuments = new List<IxDocument>(); foreach (var document in documents) { IxDocument temp = phrase.SearchResult.documents.Where(x => x.title == document.title).FirstOrDefault(); if (temp == null) { newDocuments.Add(document); } } documents = newDocuments; } } //sortujemy i zwracamy wynik documents = documents.OrderByDescending(x => x.rank).ToList(); result.documents = documents.ToArray(); return result; }