private List <LinkedList <T> > ConvertMultiSearchResultToList(MultiSearchResult multiSearchResult) { List <LinkedList <T> > result = new List <LinkedList <T> >(); List <LinkedList <ViterbiNode> > paths = multiSearchResult.GetTokenizedResultsList(); foreach (LinkedList <ViterbiNode> path in paths) { var tokens = new LinkedList <T>(); foreach (ViterbiNode node in path) { int wordId = node.WordId; if (node.Type == ViterbiNode.NodeType.KNOWN && wordId == -1) { // Do not include BOS/EOS continue; } T token = tokenFactory.CreateToken( wordId, node.Surface, node.Type, node.StartIndex, dictionaryMap[node.Type] ); tokens.AddLast(token); } result.Add(tokens); } return(result); }
/** * Tokenize input sentence. Up to maxCount different paths of cost at most OPT + costSlack are returned ordered in ascending order by cost, where OPT is the optimal solution. * * @param text sentence to tokenize * @param maxCount maximum number of paths * @param costSlack maximum cost slack of a path * @return instance of MultiSearchResult containing the tokenizations */ private MultiSearchResult CreateMultiSearchResult(string text, int maxCount, int costSlack) { ViterbiLattice lattice = viterbiBuilder.Build(text); MultiSearchResult multiSearchResult = viterbiSearcher.SearchMultiple(lattice, maxCount, costSlack); return(multiSearchResult); }
public void TestMergerTooFew() { int maxCount = 5; int costSlack = 3; MultiSearchMerger merger = new MultiSearchMerger(maxCount, costSlack); List <MultiSearchResult> results = new List <MultiSearchResult>(); string[][] surfaces1 = { new string[] { "a", "b" }, new string[] { "c", "d" }, new string[] { "e", "f" } }; int[] costs1 = { 1, 2, 5 }; results.Add(MakeResult(surfaces1, costs1)); string[][] surfaces2 = { new string[] { "a", "b" }, new string[] { "c", "d" } }; int[] costs2 = { 1, 2 }; results.Add(MakeResult(surfaces2, costs2)); string[][] surfaces3 = { new string[] { "a", "b" } }; int[] costs3 = { 5 }; results.Add(MakeResult(surfaces3, costs3)); MultiSearchResult mergedResult = merger.Merge(results); Assert.AreEqual(4, mergedResult.Count); Assert.AreEqual(7, mergedResult.GetCost(0)); Assert.AreEqual(8, mergedResult.GetCost(1)); Assert.AreEqual(8, mergedResult.GetCost(2)); Assert.AreEqual(9, mergedResult.GetCost(3)); Assert.AreEqual("a b a b a b", GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(0))); Assert.AreEqual("c d a b a b", GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(1))); Assert.AreEqual("a b c d a b", GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(2))); Assert.AreEqual("c d c d a b", GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(3))); }
/** * Tokenizes the provided text and returns up to maxCount lists of tokens with various feature information. * Each list corresponds to a possible tokenization with cost at most OPT + costSlack, where OPT is the optimal solution. * <p> * This method is thread safe * * @param text text to tokenize * @param maxCount maximum number of different tokenizations * @param costSlack maximum cost slack of a tokenization * @param <T> token type * @return list of Token, not null */ protected List <LinkedList <T> > CreateMultiTokenList(string text, int maxCount, int costSlack) { if (!split) { return(ConvertMultiSearchResultToList(CreateMultiSearchResult(text, maxCount, costSlack))); } List <int> splitPositions = GetSplitPositions(text); if (splitPositions.Count == 0) { return(ConvertMultiSearchResultToList(CreateMultiSearchResult(text, maxCount, costSlack))); } List <MultiSearchResult> results = new List <MultiSearchResult>(); int offset = 0; foreach (int position in splitPositions) { results.Add(CreateMultiSearchResult(text.Substring(offset, position + 1 - offset), maxCount, costSlack)); offset = position + 1; } if (offset < text.Length) { results.Add(CreateMultiSearchResult(text.Substring(offset), maxCount, costSlack)); } MultiSearchMerger merger = new MultiSearchMerger(maxCount, costSlack); MultiSearchResult mergedResult = merger.Merge(results); return(ConvertMultiSearchResultToList(mergedResult)); }
List <List <T> > ConvertMultiSearchResultToList(MultiSearchResult multiSearchResult) { var result = new List <List <T> >(); var paths = multiSearchResult.TokenizedResults; foreach (var path in paths) { var tokens = new List <T>(); foreach (var node in path) { var wordId = node.WordId; if (node.Type == ViterbiNode.NodeType.Known && wordId == -1) { // Do not include BOS/EOS continue; } var token = TokenFactory.CreateToken( wordId, node.Surface, node.Type, node.StartIndex, DictionaryMap[node.Type] ); tokens.Add(token); } result.Add(tokens); } return(result); }
public void TestMergerTooFew() { const int maxCount = 5; const int costSlack = 3; var merger = new MultiSearchMerger(maxCount, costSlack); var results = new List <MultiSearchResult>(); var surfaces1 = new string[][] { new string[] { "a", "b" }, new string[] { "c", "d" }, new string[] { "e", "f" } }; var costs1 = new int[] { 1, 2, 5 }; results.Add(MakeResult(surfaces1, costs1)); var surfaces2 = new string[][] { new string[] { "a", "b" }, new string[] { "c", "d" } }; var costs2 = new int[] { 1, 2 }; results.Add(MakeResult(surfaces2, costs2)); var surfaces3 = new string[][] { new string[] { "a", "b" } }; var costs3 = new int[] { 5 }; results.Add(MakeResult(surfaces3, costs3)); MultiSearchResult mergedResult = merger.Merge(results); mergedResult.Count.Is(4); mergedResult.GetCost(0).Is(7); mergedResult.GetCost(1).Is(8); mergedResult.GetCost(2).Is(8); mergedResult.GetCost(3).Is(9); GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(0)).Is("a b a b a b"); GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(1)).Is("c d a b a b"); GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(2)).Is("a b c d a b"); GetSpaceSeparatedTokens(mergedResult.GetTokenizedResult(3)).Is("c d c d a b"); }
private MultiSearchResult MakeResult(string[][] surfaces, int[] cost) { MultiSearchResult ret = new MultiSearchResult(); for (int i = 0; i < surfaces.Length; i++) { ret.Add(MakeNodes(surfaces[i]), cost[i]); } return(ret); }
private async void search_button_Click(object sender, EventArgs e) { // Written, 10.12.2019 this.searchInput_textBox.Enabled = false; this.search_button.Enabled = false; this.search_button.Text = "Searching.."; if (!String.IsNullOrEmpty(this.searchInput_textBox.Text)) { this.preUpdateLists(this.searchResults_listView); await this.updateSearchMediaActionsAsync(); MultiSearchResult multiSearch = await MultiSearchResult.searchAsync(this.searchInput_textBox.Text, 1); List <ListViewItem> items = new List <ListViewItem>(); for (int i = 0; i < ApplicationInfomation.NUMBER_OF_ITEMS_PER_PAGE; i++) { MediaSearchResult media = multiSearch.movie_results[i]; if (media == null) { media = multiSearch.tv_results[i]; } if (media != null) { string mediaTypeString = media is MovieSearchResult ? "Movie" : media is TvSearchResult ? "Tv" : "Null"; string[] subItems = new string[] { media.name, media.overview, media.release_date, media.vote_average.ToString(), mediaTypeString }; items.Add(new ListViewItem(subItems) { Tag = media }); } } this.postUpdateLists(this.searchResults_listView, items.ToArray()); } this.searchInput_textBox.Enabled = true; this.search_button.Enabled = true; this.search_button.Text = "Search"; }
static async Task Main(string[] args) { // Written, 29.11.2019 Console.WriteLine("The Library v1.1 Multi-Search Test\nEnter Phrase and press Enter to search for movies, tv series and people as a multi-search request."); string searchPhrase = Console.ReadLine(); MultiSearchResult multiSearch = null; Console.WriteLine("\n\nMulti-Search Function\n-------------------------------------------"); try { multiSearch = await MultiSearchResult.searchAsync(searchPhrase, 1); } catch (AggregateException ex) { string exMessage = ex.Message; for (int i = 0; i < ex.InnerExceptions.Count; i++) { exMessage += String.Format("\n{0}.) {1}", i + 1, ex.InnerExceptions[i].Message); } Console.WriteLine("An error occured while performing multi-search function: {0}", exMessage); } int totalResults = 0; for (int i = 0; i < ApplicationInfomation.NUMBER_OF_ITEMS_PER_PAGE; i++) { MovieSearchResult movie = multiSearch.movies[i]; if (movie != null) { Console.WriteLine("\t[MOVIE] {0} ({1})", movie.name, movie.release_date); totalResults++; } else { TvSearchResult tvSeries = multiSearch.tvSeries[i]; if (tvSeries != null) { Console.WriteLine("\t[TV] {0} ({1})", tvSeries.name, tvSeries.release_date); totalResults++; } else { PeopleSearchResult person = multiSearch.people[i]; if (person != null) { Console.WriteLine("\t[PERSON] {0} ({1})", person.id, person.profile_path); totalResults++; } } } } Console.WriteLine("Total Results: {0}", totalResults); Console.WriteLine("\n\nPress R to restart or press any key to exit"); if (Console.ReadKey().Key == ConsoleKey.R) { Console.Clear(); await Main(null); } }
public async Task <List <MultiSearchResult> > MultiSearch(string searchTerm, MultiSearchFilter filter, CancellationToken cancellationToken) { var lang = await DefaultLanguageCode(null); var model = new List <MultiSearchResult>(); var movieDbData = (await _movieDbApi.MultiSearch(searchTerm, lang, cancellationToken)).results; var lidarrSettings = await _lidarrSettings.GetSettingsAsync(); if (lidarrSettings.Enabled && filter.Music) { var artistResult = await _musicApi.SearchArtist(searchTerm); foreach (var artist in artistResult) { model.Add(new MultiSearchResult { MediaType = "Artist", Title = artist.Name, Id = artist.Id }); } } foreach (var multiSearch in movieDbData) { if (DemoCheck(multiSearch.title) || DemoCheck(multiSearch.name)) { continue; } var result = new MultiSearchResult { MediaType = multiSearch.media_type, Poster = multiSearch.poster_path, Overview = multiSearch.overview }; if (multiSearch.media_type.Equals("movie", StringComparison.InvariantCultureIgnoreCase) && filter.Movies) { if (multiSearch.release_date.HasValue() && DateTime.TryParse(multiSearch.release_date, out var releaseDate)) { result.Title = $"{multiSearch.title} ({releaseDate.Year})"; } else { result.Title = multiSearch.title; } } else if (multiSearch.media_type.Equals("tv", StringComparison.InvariantCultureIgnoreCase) && filter.TvShows) { if (multiSearch.release_date.HasValue() && DateTime.TryParse(multiSearch.release_date, out var releaseDate)) { result.Title = $"{multiSearch.name} ({releaseDate.Year})"; } else { result.Title = multiSearch.name; } } else if (multiSearch.media_type.Equals("person", StringComparison.InvariantCultureIgnoreCase) && filter.People) { result.Title = multiSearch.name; } else { continue; } result.Id = multiSearch.id.ToString(); model.Add(result); } return(model); }
// Run the query and combine results across multiple services static async Task <(int, List <MultiSearchResult>, MultiSearchFacets)> RunQueryAsync(string query, int pageNumber, int pageSize, string searchFields, string facets, List <Service> services) { // Page results from all services var searchResults = new List <IAsyncEnumerator <MultiSearchResultsPage> >(); foreach (Service service in services) { IAsyncEnumerable <MultiSearchResultsPage> response = SearchAsync(service, query, pageSize, searchFields, facets); searchResults.Add(response.GetAsyncEnumerator()); } // Merge each individual page from every service // Sort the combined page by result score int currentPageNumber = 0; var currentPage = new List <MultiSearchResult>(); var mergedFacets = new MultiSearchFacets(); do { // Combine the current page of results from each service // If the service has no more results, it is discarded var resultPages = new List <MultiSearchResultsPage>(); var nextSearchResults = new List <IAsyncEnumerator <MultiSearchResultsPage> >(); foreach (IAsyncEnumerator <MultiSearchResultsPage> pageEnumerator in searchResults) { if (await pageEnumerator.MoveNextAsync()) { resultPages.Add(pageEnumerator.Current); nextSearchResults.Add(pageEnumerator); } } searchResults = nextSearchResults; var mergedSearchResults = new List <MultiSearchResult>(); foreach (MultiSearchResultsPage resultPage in resultPages) { foreach (SearchResult <BookModel> result in resultPage.Page) { mergedSearchResults.Add(new MultiSearchResult { Service = resultPage.Service, Result = result }); } if (resultPage.Facets != null) { MergeFacets(resultPage.Facets, mergedFacets); } } // Sort the combined pages by score descending mergedSearchResults.Sort((a, b) => { MultiSearchResult resultA = a; MultiSearchResult resultB = b; if (resultA.Result.Score.HasValue && resultB.Result.Score.HasValue) { return(resultB.Result.Score.Value.CompareTo(resultA.Result.Score.Value)); } if (resultA.Result.Score.HasValue && !resultB.Result.Score.HasValue) { return(-1); } if (!resultA.Result.Score.HasValue && resultB.Result.Score.HasValue) { return(1); } return(0); }); // Return sub-pages of results from the combined page foreach (MultiSearchResult mergedSearchResult in mergedSearchResults) { currentPage.Add(mergedSearchResult); if (currentPage.Count == pageSize) { if (currentPageNumber == pageNumber) { return(currentPageNumber, currentPage, mergedFacets); } currentPage.Clear(); currentPageNumber++; } } }while (searchResults.Any()); // Return any leftover results as the last page return(currentPageNumber, currentPage, mergedFacets); }