public PartialFindResult<Artist> Find(ArtistQueryParams queryParams) { var isMoveToTopQuery = (queryParams.Common.MoveExactToTop && queryParams.Common.NameMatchMode != NameMatchMode.StartsWith && queryParams.Common.NameMatchMode != NameMatchMode.Exact && queryParams.Paging.Start == 0 && !string.IsNullOrEmpty(queryParams.Common.Query)); if (isMoveToTopQuery) { return GetArtistsMoveExactToTop(queryParams); } var query = CreateQuery(queryParams); var ids = query .OrderBy(queryParams.SortRule, LanguagePreference) .Select(s => s.Id) .Paged(queryParams.Paging) .ToArray(); var artists = SortByIds(context .Query() .Where(s => ids.Contains(s.Id)) .ToArray(), ids); var count = (queryParams.Paging.GetTotalCount ? query.Count() : 0); return new PartialFindResult<Artist>(artists, count, queryParams.Common.Query, false); }
/// <summary> /// Get songs, searching by exact matches FIRST. /// This mode does not support paging. /// </summary> private PartialFindResult<Artist> GetArtistsMoveExactToTop(ArtistQueryParams queryParams) { var sortRule = queryParams.SortRule; var maxResults = queryParams.Paging.MaxEntries; var getCount = queryParams.Paging.GetTotalCount; // Exact query contains the "exact" matches. // Note: the matched name does not have to be in user's display language, it can be any name. // The songs are sorted by user's display language though var exactQ = CreateQuery(queryParams, NameMatchMode.StartsWith); int count; int[] ids; var exactResults = exactQ .OrderBy(sortRule, LanguagePreference) .Select(s => s.Id) .Take(maxResults) .ToArray(); if (exactResults.Length >= maxResults) { ids = exactResults; count = getCount ? CreateQuery(queryParams).Count() : 0; } else { var directQ = CreateQuery(queryParams); var direct = directQ .OrderBy(sortRule, LanguagePreference) .Select(s => s.Id) .Take(maxResults) .ToArray(); ids = exactResults .Concat(direct) .Distinct() .Take(maxResults) .ToArray(); count = getCount ? directQ.Count() : 0; } var artist = SortByIds(context .Query() .Where(s => ids.Contains(s.Id)) .ToArray(), ids); return new PartialFindResult<Artist>(artist, count, queryParams.Common.Query, true); }
private IQueryable<Artist> CreateQuery( ArtistQueryParams queryParams, NameMatchMode? nameMatchMode = null) { var query = context.Query() .Where(s => !s.Deleted) .WhereHasName_Canonized(queryParams.Common.Query, matchMode: nameMatchMode ?? queryParams.Common.NameMatchMode) .WhereDraftsOnly(queryParams.Common.DraftOnly) .WhereStatusIs(queryParams.Common.EntryStatus) .WhereHasType(queryParams.ArtistTypes) .WhereHasTag(queryParams.Tag) .WhereIsFollowedByUser(queryParams.UserFollowerId); return query; }
public ActionResult ByName(string query, ContentLanguagePreference? lang, int? start, int? maxResults, NameMatchMode? nameMatchMode, string callback, DataFormat format = DataFormat.Auto) { if (string.IsNullOrEmpty(query)) return Object(new PartialFindResult<SongForApiContract>(), format, callback); var param = new ArtistQueryParams(query, new ArtistType[] { }, 0, defaultMax, false, true, NameMatchMode.Exact, ArtistSortRule.Name, false); if (start.HasValue) param.Paging.Start = start.Value; if (maxResults.HasValue) param.Paging.MaxEntries = Math.Min(maxResults.Value, defaultMax); if (nameMatchMode.HasValue) param.Common.NameMatchMode = nameMatchMode.Value; var songs = Service.FindArtists(s => new ArtistForApiContract(s, lang ?? ContentLanguagePreference.Default), param); return Object(songs, format, callback); }
public ActionResult FindJson(string term, string artistTypes) { var matchMode = NameMatchMode.Auto; term = FindHelpers.GetMatchModeAndQueryForSearch(term, ref matchMode); var typeVals = !string.IsNullOrEmpty(artistTypes) ? artistTypes.Split(',').Select(EnumVal<ArtistType>.Parse).ToArray() : new ArtistType[] {}; var queryParams = new ArtistQueryParams(term, typeVals, 0, 20, false, false, matchMode, ArtistSortRule.Name, true); var artists = Service.FindArtists(queryParams); return Json(artists); }
// // GET: /Artist/ public ActionResult Index(IndexRouteParams routeParams) { WebHelper.VerifyUserAgent(Request); var artistType = routeParams.artistType ?? ArtistType.Unknown; var filter = routeParams.filter; var page = routeParams.page; var draftsOnly = routeParams.draftsOnly; var matchMode = routeParams.matchMode ?? NameMatchMode.Auto; var sortRule = routeParams.sort ?? ArtistSortRule.Name; if (matchMode == NameMatchMode.Auto && filter != null && filter.Length <= 2) matchMode = NameMatchMode.StartsWith; var queryParams = new ArtistQueryParams(filter, artistType != ArtistType.Unknown ? new[] { artistType } : new ArtistType[] { }, ((page ?? 1) - 1) * 30, 30, draftsOnly ?? false, true, matchMode, sortRule, false); var result = Service.FindArtists(queryParams); if (page == null && result.TotalCount == 1 && result.Items.Length == 1) { return RedirectToAction("Details", new { id = result.Items[0].Id }); } var model = new ArtistIndex(result, filter, artistType, draftsOnly, sortRule, page, routeParams); return View(model); }
public PartialFindResult <Artist> Find(ISession session, ArtistQueryParams queryParams) { var query = queryParams.Common.Query; var artistTypes = queryParams.ArtistTypes; var draftsOnly = queryParams.Common.DraftOnly; var sortRule = queryParams.SortRule; var start = queryParams.Paging.Start; var maxResults = queryParams.Paging.MaxEntries; string originalQuery = query; if (string.IsNullOrWhiteSpace(query)) { bool filterByArtistType = artistTypes.Any(); Artist art = null; var q = session.QueryOver(() => art) .Where(s => !s.Deleted); if (draftsOnly) { q = q.Where(a => a.Status == EntryStatus.Draft); } if (filterByArtistType) { q = q.WhereRestrictionOn(s => s.ArtistType).IsIn(artistTypes); } q = AddOrder(q, sortRule, LanguagePreference); var artists = q .TransformUsing(new DistinctRootEntityResultTransformer()) .Skip(start) .Take(maxResults) .List(); var count = (queryParams.Paging.GetTotalCount ? GetArtistCount(session, queryParams) : 0); return(new PartialFindResult <Artist>(artists.ToArray(), count, originalQuery, false)); } else { query = query.Trim(); // Note: Searching by SortNames can be disabled in the future because all names should be included in the Names list anyway. var directQ = session.Query <Artist>() .Where(s => !s.Deleted); if (draftsOnly) { directQ = directQ.Where(a => a.Status == EntryStatus.Draft); } if (artistTypes.Any()) { directQ = directQ.Where(s => artistTypes.Contains(s.ArtistType)); } directQ = AddNameMatchFilter(directQ, query, queryParams.Common.NameMatchMode); directQ = AddOrder(directQ, sortRule, LanguagePreference); var direct = directQ .ToArray(); var additionalNamesQ = session.Query <ArtistName>() .Where(m => !m.Artist.Deleted); if (draftsOnly) { additionalNamesQ = additionalNamesQ.Where(a => a.Artist.Status == EntryStatus.Draft); } additionalNamesQ = additionalNamesQ.FilterByArtistName(query, null, queryParams.Common.NameMatchMode); additionalNamesQ = additionalNamesQ.FilterByArtistType(artistTypes); var additionalNames = AddOrder(additionalNamesQ .Select(m => m.Artist), sortRule, LanguagePreference) .Distinct() .Take(maxResults) //.FetchMany(s => s.Names) .ToArray() .Where(a => !direct.Contains(a)); var entries = direct.Concat(additionalNames) .Skip(start) .Take(maxResults) .ToArray(); bool foundExactMatch = false; if (queryParams.Common.MoveExactToTop) { var exactMatch = entries .Where(e => e.Names.Any(n => n.Value.StartsWith(query, StringComparison.InvariantCultureIgnoreCase))) .ToArray(); if (exactMatch.Any()) { entries = CollectionHelper.MoveToTop(entries, exactMatch).ToArray(); foundExactMatch = true; } } var count = (queryParams.Paging.GetTotalCount ? GetArtistCount(session, queryParams) : 0); return(new PartialFindResult <Artist>(entries.ToArray(), count, originalQuery, foundExactMatch)); } }
private int GetArtistCount(ISession session, ArtistQueryParams queryParams) { var query = queryParams.Common.Query; var artistTypes = queryParams.ArtistTypes; var draftsOnly = queryParams.Common.DraftOnly; var nameMatchMode = queryParams.Common.NameMatchMode; if (string.IsNullOrWhiteSpace(query)) { var q = session.Query <Artist>() .Where(s => !s.Deleted && (!artistTypes.Any() || artistTypes.Contains(s.ArtistType))); if (draftsOnly) { q = q.Where(a => a.Status == EntryStatus.Draft); } return(q.Count()); } query = query.Trim(); var directQ = session.Query <Artist>() .Where(s => !s.Deleted); if (artistTypes.Any()) { directQ = directQ.Where(s => artistTypes.Contains(s.ArtistType)); } if (draftsOnly) { directQ = directQ.Where(a => a.Status == EntryStatus.Draft); } directQ = AddNameMatchFilter(directQ, query, nameMatchMode); var direct = directQ.ToArray(); var additionalNamesQ = session.Query <ArtistName>() .Where(m => !m.Artist.Deleted); if (draftsOnly) { additionalNamesQ = additionalNamesQ.Where(a => a.Artist.Status == EntryStatus.Draft); } additionalNamesQ = additionalNamesQ.FilterByArtistName(query, null, nameMatchMode); additionalNamesQ = additionalNamesQ.FilterByArtistType(artistTypes); var additionalNames = additionalNamesQ .Select(m => m.Artist) .Distinct() .ToArray() .Where(a => !direct.Contains(a)) .ToArray(); return(direct.Count() + additionalNames.Count()); }
public PartialFindResult<ArtistForApiContract> GetList( string query = "", ArtistTypes artistTypes = ArtistTypes.Nothing, string tag = null, int? followedByUserId = null, EntryStatus? status = null, int start = 0, int maxResults = defaultMax, bool getTotalCount = false, ArtistSortRule sort = ArtistSortRule.Name, NameMatchMode nameMatchMode = NameMatchMode.Exact, ArtistOptionalFields fields = ArtistOptionalFields.None, ContentLanguagePreference lang = ContentLanguagePreference.Default) { query = FindHelpers.GetMatchModeAndQueryForSearch(query, ref nameMatchMode); var types = ArtistHelper.GetArtistTypesFromFlags(artistTypes); var param = new ArtistQueryParams(query, types, start, Math.Min(maxResults, absoluteMax), false, getTotalCount, nameMatchMode, sort, false) { Tag = tag, UserFollowerId = followedByUserId ?? 0 }; param.Common.EntryStatus = status; var ssl = WebHelper.IsSSL(Request); var artists = service.FindArtists(s => new ArtistForApiContract(s, lang, thumbPersister, ssl, fields), param); return artists; }