async tree search (#12344)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models.ContentEditing
|
||||
{
|
||||
|
||||
[DataContract(Name = "searchResults", Namespace = "")]
|
||||
public class EntitySearchResults : IEnumerable<SearchResultEntity?>
|
||||
{
|
||||
private readonly IEnumerable<SearchResultEntity?> _results;
|
||||
|
||||
public EntitySearchResults(IEnumerable<SearchResultEntity?> results, long totalFound)
|
||||
{
|
||||
_results = results;
|
||||
TotalResults = totalFound;
|
||||
}
|
||||
|
||||
[DataMember(Name = "totalResults")]
|
||||
public long TotalResults { get; set; }
|
||||
|
||||
public IEnumerator<SearchResultEntity?> GetEnumerator() => _results.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_results).GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Runtime.Serialization;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models.ContentEditing
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
|
||||
@@ -22,6 +23,6 @@ namespace Umbraco.Cms.Core.Trees
|
||||
/// A starting point for the search, generally a node id, but for members this is a member type alias
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null);
|
||||
Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
@@ -193,9 +195,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
/// methods might be used in things like pickers in the content editor.
|
||||
/// </remarks>
|
||||
[HttpGet]
|
||||
public IDictionary<string, TreeSearchResult> SearchAll(string query)
|
||||
public async Task<IDictionary<string, TreeSearchResult>> SearchAll(string query)
|
||||
{
|
||||
var result = new Dictionary<string, TreeSearchResult>();
|
||||
var result = new ConcurrentDictionary<string, TreeSearchResult>();
|
||||
|
||||
if (string.IsNullOrEmpty(query))
|
||||
{
|
||||
@@ -204,6 +206,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
|
||||
var allowedSections = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.AllowedSections.ToArray();
|
||||
|
||||
var searchTasks = new List<Task>();
|
||||
foreach (KeyValuePair<string, SearchableApplicationTree> searchableTree in _searchableTreeCollection
|
||||
.SearchableApplicationTrees.OrderBy(t => t.Value.SortOrder))
|
||||
{
|
||||
@@ -218,21 +221,32 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
var rootNodeDisplayName = Tree.GetRootNodeDisplayName(tree, _localizedTextService);
|
||||
if (rootNodeDisplayName is not null)
|
||||
{
|
||||
result[rootNodeDisplayName] = new TreeSearchResult
|
||||
{
|
||||
Results = searchableTree.Value.SearchableTree.Search(query, 200, 0, out var total).WhereNotNull(),
|
||||
TreeAlias = searchableTree.Key,
|
||||
AppAlias = searchableTree.Value.AppAlias,
|
||||
JsFormatterService = searchableTree.Value.FormatterService,
|
||||
JsFormatterMethod = searchableTree.Value.FormatterMethod
|
||||
};
|
||||
searchTasks.Add(ExecuteSearchAsync(query, searchableTree, rootNodeDisplayName,result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await Task.WhenAll(searchTasks);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static async Task ExecuteSearchAsync(
|
||||
string query,
|
||||
KeyValuePair<string, SearchableApplicationTree> searchableTree,
|
||||
string rootNodeDisplayName,
|
||||
ConcurrentDictionary<string, TreeSearchResult> result)
|
||||
{
|
||||
var searchResult = new TreeSearchResult
|
||||
{
|
||||
Results = (await searchableTree.Value.SearchableTree.SearchAsync(query, 200, 0)).WhereNotNull(),
|
||||
TreeAlias = searchableTree.Key,
|
||||
AppAlias = searchableTree.Value.AppAlias,
|
||||
JsFormatterService = searchableTree.Value.FormatterService,
|
||||
JsFormatterMethod = searchableTree.Value.FormatterMethod
|
||||
};
|
||||
|
||||
result.AddOrUpdate(rootNodeDisplayName, _=> searchResult, (_,_) => searchResult);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the path for a given node ID
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -366,9 +367,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
var menuItem = menu.Items.Add<TAction>(LocalizedTextService, hasSeparator, opensDialog);
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
return _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Document, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
var results = _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Document, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -180,8 +181,11 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
return menu;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.DocumentType, query, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
var results = _treeSearcher.EntitySearch(UmbracoObjectTypes.DocumentType, query, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -170,7 +171,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
return menu;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.DataType, query, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
var results = _treeSearcher.EntitySearch(UmbracoObjectTypes.DataType, query, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -183,9 +184,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
return HasPathAccess(entity, queryStrings);
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
return _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
var results = _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Media, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -145,8 +146,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
return menu;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.MediaType, query, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
var results = _treeSearcher.EntitySearch(UmbracoObjectTypes.MediaType, query, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -156,9 +157,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
return menu;
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
return _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Member, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
var results = _treeSearcher.ExamineSearch(query, UmbracoEntityTypes.Member, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -63,8 +64,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
.Select(dt => CreateTreeNode(dt, Constants.ObjectTypes.MemberType, id, queryStrings, dt?.Icon ?? Constants.Icons.MemberType, false));
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.MemberType, query, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
var results = _treeSearcher.EntitySearch(UmbracoObjectTypes.MemberType, query, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -156,7 +157,10 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
|
||||
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.Template, query, pageSize, pageIndex, out totalFound, searchFrom);
|
||||
public async Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null)
|
||||
{
|
||||
var results = _treeSearcher.EntitySearch(UmbracoObjectTypes.Template, query, pageSize, pageIndex, out long totalFound, searchFrom);
|
||||
return new EntitySearchResults(results, totalFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user