public virtual SearchResult <SearchableBase> Search(SearchTextQuery query) { var searchRequest = GetSearchDescriptor() .Query(q => q.Bool(b => b .Should(GetQueryContainers(query.Text)) .MinimumShouldMatch(MinimumShouldMatch.Fixed(MinimumShouldMatches)))) .PostFilter(pf => pf.Bool(b => b.Must(GetSearchPostFilters(query)))); ApplyAggregations(searchRequest, query); _searchSorting.Apply(searchRequest, query); _searchPagingHelper.Apply(searchRequest, query); if (query.ApplyHighlights) { ApplyHighlight(searchRequest); } var queryResult = _elasticSearchRepository.SearchByIndex(searchRequest); var searchResult = ParseResults(queryResult); return(searchResult); }
/// <summary> /// Adds a filter for a list of names. /// </summary> /// <typeparam name="T">Entry name type</typeparam> /// <param name="query">Entry name query. Cannot be null.</param> /// <param name="textQuery">Name query filter. Cannot be null.</param> /// <returns>Filtered query. Cannot be null.</returns> public static IQueryable <T> AddEntryNameFilter <T>(IQueryable <T> query, SearchTextQuery textQuery) where T : LocalizedString { if (textQuery.IsEmpty) { return(query); } var nameFilter = textQuery.Query; switch (textQuery.MatchMode) { case NameMatchMode.Exact: return(query.Where(m => m.Value == nameFilter)); case NameMatchMode.Partial: return(query.Where(m => m.Value.Contains(nameFilter))); case NameMatchMode.StartsWith: return(query.Where(m => m.Value.StartsWith(nameFilter))); case NameMatchMode.Words: var words = textQuery.Words; foreach (var word in words.Take(MaxSearchWords)) { var temp = word; query = query.Where(q => q.Value.Contains(temp)); } return(query); } return(query); }
public LyricsForSongContract GetRandomLyricsForSong(string query) { return(HandleQuery(session => { var songContract = Find(session, new SongQueryParams(SearchTextQuery.Create(query), new SongType[] { }, 0, 10, false, SongSortRule.Name, false, true, null) { AdvancedFilters = new[] { new AdvancedSearchFilter { FilterType = AdvancedFilterType.Lyrics, Param = AdvancedSearchFilter.Any } } }).Items; if (!songContract.Any()) { return null; } var songIds = songContract.Select(s => s.Id).ToArray(); var songs = session.Query <Song>().Where(s => songIds.Contains(s.Id)).ToArray(); var allLyrics = songs.SelectMany(s => s.Lyrics).ToArray(); if (!allLyrics.Any()) { return null; } var lyrics = allLyrics[new Random().Next(allLyrics.Length)]; return new LyricsForSongContract(lyrics); })); }
private SearchTextQuery ProcessAdvancedSearch(SearchTextQuery textQuery, SongQueryParams queryParams) { if (textQuery.IsEmpty || textQuery.MatchMode == NameMatchMode.Exact || textQuery.MatchMode == NameMatchMode.StartsWith || !textQuery.OriginalQuery.StartsWith("!")) { return(textQuery); } var parsed = SearchParser.ParseQuery(textQuery.OriginalQuery.Substring(1)); var artistNames = parsed.GetValues("artist").ToArray(); if (artistNames.Any()) { queryParams.ArtistNames = artistNames; } var words = parsed.GetValues("").ToArray(); if (words.Any()) { queryParams.Common.TextQuery = new SearchTextQuery(textQuery.Query, NameMatchMode.Words, textQuery.OriginalQuery, words); return(queryParams.Common.TextQuery); } else { return(textQuery); } }
private IQueryable <Album> CreateQuery( AlbumQueryParams queryParams, ParsedAlbumQuery parsedQuery, NameMatchMode?nameMatchMode = null) { var artistIds = EntryIdsCollection.CreateWithFallback(queryParams.ArtistParticipation.ArtistIds.Ids, parsedQuery.ArtistId); var textQuery = SearchTextQuery.Create(parsedQuery.Name, nameMatchMode ?? queryParams.Common.NameMatchMode); var query = Query <Album>() .WhereIsDeleted(queryParams.Deleted) .WhereHasName(textQuery, allowCatNum: true) .WhereStatusIs(queryParams.Common.EntryStatus) .WhereHasArtistParticipationStatus(queryParams.ArtistParticipation, artistIds, querySource.OfType <Artist>()) .WhereHasBarcode(queryParams.Barcode) .WhereHasType(queryParams.AlbumType) .WhereHasTags(queryParams.TagIds, queryParams.ChildTags) .WhereHasTags(queryParams.Tags) .WhereHasTag(parsedQuery.TagName) .WhereReleaseDateIsAfter(queryParams.ReleaseDateAfter) .WhereReleaseDateIsBefore(queryParams.ReleaseDateBefore) .WhereSortBy(queryParams.SortRule) .WhereMatchFilters(queryParams.AdvancedFilters); return(query); }
public void ParseTextQuery_Id() { var result = songSearch.ParseTextQuery(SearchTextQuery.Create("id:3939")); Assert.IsFalse(result.HasNameQuery, "HasNameQuery"); Assert.AreEqual(3939, result.Id, "Id query"); }
public ParsedSongQuery ParseTextQuery(SearchTextQuery textQuery) { var query = textQuery.OriginalQuery; if (string.IsNullOrWhiteSpace(query)) { return(new ParsedSongQuery()); } var trimmed = query.Trim(); var term = GetTerm(trimmed, "id", "tag", "artist-tag", "artist-type", "publish-date"); return((term?.PropertyName) switch { "tag" => new ParsedSongQuery { TagName = term.Value }, "artist-tag" => new ParsedSongQuery { ArtistTag = term.Value }, "artist-type" => new ParsedSongQuery { ArtistType = EnumVal <ArtistType> .ParseSafe(term.Value, ArtistType.Unknown) }, "id" => new ParsedSongQuery { Id = PrimitiveParseHelper.ParseIntOrDefault(term.Value, 0) }, "publish-date" => ParseDateRange(term.Value), _ => ParseReferenceQuery(trimmed, query) ?? new ParsedSongQuery { Name = textQuery }, });
public void ParseTextQuery_Name() { var result = songSearch.ParseTextQuery(SearchTextQuery.Create("Hatsune Miku")); Assert.IsTrue(result.HasNameQuery, "HasNameQuery"); Assert.AreEqual("Hatsune Miku", result.Name.Query, "Name query"); }
public void ParseTextQuery_DateRange() { var result = songSearch.ParseTextQuery(SearchTextQuery.Create("publish-date:2015/9/3-2015/10/1")); Assert.AreEqual(new DateTime(2015, 9, 3), result.PublishedAfter, "Publish date after"); Assert.AreEqual(new DateTime(2015, 10, 1), result.PublishedBefore, "Publish date before"); }
public T FindFirst <T>(Func <Song, ISession, T> fac, string[] query, NameMatchMode nameMatchMode) where T : class { return(HandleQuery(session => { foreach (var q in query.Where(q => !string.IsNullOrWhiteSpace(q))) { var result = Find(session, new SongQueryParams { Common = new CommonSearchParams { TextQuery = SearchTextQuery.Create(q, nameMatchMode), OnlyByName = true, MoveExactToTop = true }, LanguagePreference = LanguagePreference, Paging = new PagingProperties(0, 30, false) }); if (result.Items.Any()) { return fac(result.Items.First(), session); } } return null; })); }
public PartialFindResult <SongInListForApiContract> GetSongs(int listId, string query = "", string songTypes = null, [FromUri] PVServices?pvServices = null, [FromUri] int[] tagId = null, [FromUri] int[] artistId = null, bool childVoicebanks = false, [FromUri] AdvancedSearchFilter[] advancedFilters = null, int start = 0, int maxResults = defaultMax, bool getTotalCount = false, SongSortRule?sort = null, NameMatchMode nameMatchMode = NameMatchMode.Auto, SongOptionalFields fields = SongOptionalFields.None, ContentLanguagePreference lang = ContentLanguagePreference.Default ) { maxResults = Math.Min(maxResults, absoluteMax); var types = EnumVal <SongType> .ParseMultiple(songTypes); return(queries.GetSongsInList( new SongListQueryParams { TextQuery = SearchTextQuery.Create(query, nameMatchMode), ListId = listId, Paging = new PagingProperties(start, maxResults, getTotalCount), PVServices = pvServices, ArtistIds = artistId, ChildVoicebanks = childVoicebanks, TagIds = tagId, SortRule = sort, AdvancedFilters = advancedFilters, SongTypes = types }, songInList => new SongInListForApiContract(songInList, lang, fields))); }
public PartialFindResult <UserForApiContract> GetList( string query = "", UserGroupId groups = UserGroupId.Nothing, DateTime?joinDateAfter = null, DateTime?joinDateBefore = null, NameMatchMode nameMatchMode = NameMatchMode.Auto, int start = 0, int maxResults = 10, bool getTotalCount = false, UserSortRule?sort = null, bool includeDisabled = false, bool onlyVerified = false, string knowsLanguage = null, UserOptionalFields fields = UserOptionalFields.None) { var queryParams = new UserQueryParams { Common = new CommonSearchParams(SearchTextQuery.Create(query, nameMatchMode), false, false), Group = groups, IncludeDisabled = includeDisabled, OnlyVerifiedArtists = onlyVerified, KnowsLanguage = knowsLanguage, JoinDateAfter = joinDateAfter, JoinDateBefore = joinDateBefore, Sort = sort ?? UserSortRule.Name, Paging = new PagingProperties(start, maxResults, getTotalCount) }; return(queries.GetUsers(queryParams, user => new UserForApiContract(user, userIconFactory, fields))); }
public static ArtistSearchTextQuery Create(SearchTextQuery textQuery) { var canonizedName = ArtistHelper.GetCanonizedName(textQuery.Query); // Can't use the existing words collection here as they are noncanonized return(new ArtistSearchTextQuery(canonizedName, textQuery.MatchMode, textQuery.OriginalQuery)); }
public ActionResult Index(string filter = null, UserGroupId?groupId = null) { var vm = new Models.User.Index { Filter = filter, GroupId = groupId }; if (!string.IsNullOrEmpty(filter)) { var queryParams = new UserQueryParams { Common = new CommonSearchParams(SearchTextQuery.Create(filter), false, false), Paging = new PagingProperties(0, 1, true), Group = groupId ?? UserGroupId.Nothing }; var result = Data.GetUsers(queryParams, u => u.Name); if (result.TotalCount == 1 && result.Items.Length == 1) { return(RedirectToAction("Profile", new { id = result.Items[0] })); } } return(View(vm)); }
public FeedResult Feed(IndexRouteParams indexParams) { WebHelper.VerifyUserAgent(Request); var pageSize = (indexParams.pageSize.HasValue ? Math.Min(indexParams.pageSize.Value, 30) : 30); var sortRule = indexParams.sort ?? SongSortRule.Name; var timeFilter = DateTimeUtils.ParseFromSimpleString(indexParams.since); var filter = indexParams.filter; var songType = indexParams.songType ?? SongType.Unspecified; var matchMode = indexParams.matchMode ?? NameMatchMode.Auto; var onlyWithPVs = indexParams.onlyWithPVs ?? false; var minScore = indexParams.minScore ?? 0; var textQuery = SearchTextQuery.Create(filter, matchMode); var queryParams = new SongQueryParams(textQuery, songType != SongType.Unspecified ? new[] { songType } : new SongType[] { }, 0, pageSize, false, sortRule, false, false, null) { TimeFilter = timeFilter, OnlyWithPVs = onlyWithPVs, ArtistIds = !indexParams.artistId.HasValue || indexParams.artistId.Value == 0 ? null : new [] { indexParams.artistId.Value }, MinScore = minScore, }; var result = Service.FindWithThumbPreferNotNico(queryParams); var fac = new SongFeedFactory(); var feed = fac.Create(result.Items, VocaUriBuilder.CreateAbsolute(Url.Action("Index", indexParams)), song => RenderPartialViewToString("SongItem", song), song => Url.Action("Details", new { id = song.Id })); return(new FeedResult(new Atom10FeedFormatter(feed))); }
public string[] FindNames(SearchTextQuery textQuery, int maxResults) { if (textQuery.IsEmpty) { return new string[] {} } ; var artistTextQuery = ArtistSearchTextQuery.Create(textQuery); var tagTextQuery = TagSearchTextQuery.Create(textQuery); return(HandleQuery(session => { var artistNames = session.Query <ArtistName>() .WhereArtistNameIs(artistTextQuery) .Where(a => !a.Artist.Deleted) .Select(n => n.Value) .OrderBy(n => n) .Distinct() .Take(maxResults) .ToArray(); var albumNames = session.Query <AlbumName>() .WhereEntryNameIs(textQuery) .Where(a => !a.Album.Deleted) .Select(n => n.Value) .OrderBy(n => n) .Distinct() .Take(maxResults) .ToArray(); var songNames = session.Query <SongName>() .WhereEntryNameIs(textQuery) .Where(a => !a.Song.Deleted) .Select(n => n.Value) .OrderBy(n => n) .Distinct() .Take(maxResults) .ToArray(); var tagNames = session.Query <TagName>() .WhereEntryNameIs(tagTextQuery) .Where(a => !a.Entry.Deleted) .Select(t => t.Value) .OrderBy(t => t) .Take(maxResults) .ToArray(); var allNames = artistNames .Concat(albumNames) .Concat(songNames) .Concat(tagNames) .Distinct() .OrderBy(n => n) .Take(maxResults) .ToArray(); return NameHelper.MoveExactNamesToTop(allNames, textQuery.Query); })); }
public void Find_NameQuotedExact() { queryParams.Common.TextQuery = SearchTextQuery.Create("\"Anger\""); var result = CallFind(); AssertTags(result, "Anger"); }
public void Find_NameMatchModeExact() { queryParams.Common.TextQuery = SearchTextQuery.Create("Anger", NameMatchMode.Exact); var result = CallFind(); AssertTags(result, "Anger"); }
public void Find_NameWords() { queryParams.Common.TextQuery = SearchTextQuery.Create("Anger"); var result = CallFind(); AssertTags(result, "Anger", "Anger [EXTEND RMX]"); }
public PartialFindResult <ReleaseEventSeriesContract> GetList( string query = "", int start = 0, int maxResults = defaultMax, bool getTotalCount = false, NameMatchMode nameMatchMode = NameMatchMode.Auto) { return(queries.FindSeries(s => new ReleaseEventSeriesContract(s), SearchTextQuery.Create(query, nameMatchMode), new PagingProperties(start, maxResults, getTotalCount))); }
public PartialFindResult <AlbumContract> Find( SearchTextQuery textQuery, DiscType discType, int start, int maxResults, bool getTotalCount, AlbumSortRule sortRule = AlbumSortRule.Name, bool moveExactToTop = false) { var queryParams = new AlbumQueryParams(textQuery, discType, start, maxResults, getTotalCount, sortRule, moveExactToTop); return(Find(queryParams)); }
protected virtual QueryContainer[] GetSearchPostFilters(SearchTextQuery query) { return(new[] { GetSearchableTypeQueryContainers(query.SearchableTypeIds), GetOnlyPinnedQueryContainer(query.OnlyPinned) }); }
/// <summary> /// Filters query by one or more tag names. /// The tag has to match at least one of the names. /// For empty list of names (or null) nothing is matched. /// The name has to be exact match (case insensitive). /// </summary> /// <param name="query">Query to be filtered. Cannot be null.</param> /// <param name="names">List of names to filter by. Can be null or empty, but in that case no tags will be matched.</param> /// <returns>Filtered query. Cannot be null.</returns> public static IQueryable <Tag> WhereHasName(this IQueryable <Tag> query, params string[] names) { names = names ?? new string[0]; var queries = names.Select(n => SearchTextQuery.Create(n, NameMatchMode.Exact)); return(query.WhereHasNameGeneric <Tag, TagName>(queries)); }
public AlbumQueryParams(SearchTextQuery textQuery, DiscType discType, int start, int maxResults, bool getTotalCount, AlbumSortRule sortRule = AlbumSortRule.Name, bool moveExactToTop = false) { Common = new CommonSearchParams(textQuery, false, moveExactToTop); Paging = new PagingProperties(start, maxResults, getTotalCount); AlbumType = discType; SortRule = sortRule; }
public PartialFindResult <SongWithAlbumAndPVsContract> FindSongs(string term, int maxResults, NameMatchMode nameMatchMode = NameMatchMode.Auto) { var sampleSize = Math.Min(maxResults * 2, 30); var results = songService.FindWithAlbum(new SongQueryParams( SearchTextQuery.Create(term, nameMatchMode), new SongType[] {}, 0, sampleSize, true, SongSortRule.Name, false, true, null), false); return(new PartialFindResult <SongWithAlbumAndPVsContract>(results.Items.Take(maxResults).ToArray(), results.TotalCount, results.Term)); }
private ParsedArtistQuery ParseTextQuery(SearchTextQuery textQuery) { if (textQuery.IsEmpty) { return(new ParsedArtistQuery()); } var trimmed = textQuery.OriginalQuery.Trim(); var term = SearchWord.GetTerm(trimmed, "id"); if (term == null) { var trimmedLc = trimmed.ToLowerInvariant(); // Optimization: check prefix, in most cases the user won't be searching by URL if (trimmedLc.StartsWith("/ar/") || trimmedLc.StartsWith("http")) { var entryId = entryUrlParser.Parse(trimmed, allowRelative: true); if (entryId.EntryType == EntryType.Artist) { return new ParsedArtistQuery { Id = entryId.Id } } ; } if (trimmedLc.StartsWith("http") || trimmedLc.StartsWith("mylist/") || trimmedLc.StartsWith("user/")) { var extUrl = new ArtistExternalUrlParser().GetExternalUrl(trimmed); if (extUrl != null) { return new ParsedArtistQuery { ExternalLinkUrl = extUrl } } ; } } else { switch (term.PropertyName) { case "id": return(new ParsedArtistQuery { Id = PrimitiveParseHelper.ParseIntOrDefault(term.Value, 0) }); } } return(new ParsedArtistQuery { Name = textQuery.Query }); }
public void QueryNameMoveExactToTop() { _queryParams = _queryParams with { Common = _queryParams.Common with { TextQuery = SearchTextQuery.Create("Tears"), MoveExactToTop = true, },
public PartialFindResult <SongForApiContract> GetList( string query = "", string songTypes = null, [FromUri] string[] tagName = null, [FromUri] int[] tagId = null, bool childTags = false, [FromUri] int[] artistId = null, ArtistAlbumParticipationStatus artistParticipationStatus = ArtistAlbumParticipationStatus.Everything, bool childVoicebanks = false, bool includeMembers = false, bool onlyWithPvs = false, [FromUri] PVServices?pvServices = null, int?since = null, int?minScore = null, int?userCollectionId = null, int?releaseEventId = null, EntryStatus?status = null, [FromUri] AdvancedSearchFilter[] advancedFilters = null, int start = 0, int maxResults = defaultMax, bool getTotalCount = false, SongSortRule sort = SongSortRule.Name, bool preferAccurateMatches = false, NameMatchMode nameMatchMode = NameMatchMode.Exact, SongOptionalFields fields = SongOptionalFields.None, ContentLanguagePreference lang = ContentLanguagePreference.Default) { var textQuery = SearchTextQuery.Create(query, nameMatchMode); var types = EnumVal <SongType> .ParseMultiple(songTypes); var param = new SongQueryParams(textQuery, types, start, Math.Min(maxResults, absoluteMax), getTotalCount, sort, false, preferAccurateMatches, null) { ArtistParticipation = { ArtistIds = artistId, Participation = artistParticipationStatus, ChildVoicebanks = childVoicebanks, IncludeMembers = includeMembers }, TagIds = tagId, Tags = tagName, ChildTags = childTags, OnlyWithPVs = onlyWithPvs, TimeFilter = since.HasValue ? TimeSpan.FromHours(since.Value) : TimeSpan.Zero, MinScore = minScore ?? 0, PVServices = pvServices, UserCollectionId = userCollectionId ?? 0, ReleaseEventId = releaseEventId ?? 0, AdvancedFilters = advancedFilters, LanguagePreference = lang }; param.Common.EntryStatus = status; var artists = service.Find(s => new SongForApiContract(s, null, lang, fields), param); return(artists); }
public void QueryTag() { queryParams.Common.TextQuery = SearchTextQuery.Create("tag:Electronic"); var result = CallFind(); Assert.AreEqual(1, result.Items.Length, "1 result"); Assert.AreEqual(1, result.TotalCount, "1 total count"); Assert.AreEqual(Db.Song, result.Items[0], "result is as expected"); }
public void QueryNameWords() { queryParams.Common.TextQuery = SearchTextQuery.Create("Tears Crystal", NameMatchMode.Words); var result = CallFind(); Assert.AreEqual(1, result.Items.Length, "1 result"); Assert.AreEqual(1, result.TotalCount, "total result count"); Assert.AreEqual("Crystal Tears", result.Items[0].DefaultName); }