Fixes back office searching

This commit is contained in:
Shannon
2021-06-23 12:46:50 -06:00
parent 37685e3b77
commit 76d206a4ba
6 changed files with 84 additions and 55 deletions

View File

@@ -8,7 +8,7 @@ using Umbraco.Core.Xml;
namespace Umbraco.Web
{
using Examine = global::Examine;
// TODO: Merge this into IPublishedContentQuery for v9!
public interface IPublishedContentQuery2 : IPublishedContentQuery
{
/// <summary>
@@ -32,7 +32,7 @@ namespace Umbraco.Web
/// </para>
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
/// </remarks>
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = Umbraco.Core.Constants.UmbracoIndexes.ExternalIndexName, ISet<string> loadedFields = null);
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = Constants.UmbracoIndexes.ExternalIndexName, ISet<string> loadedFields = null);
}
/// <summary>

View File

@@ -180,7 +180,7 @@ namespace Umbraco.Web.Models.Mapping
target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]";
var culture = context.GetCulture();
var culture = context.GetCulture()?.ToLowerInvariant();
if(culture.IsNullOrWhiteSpace() == false)
{
target.Name = source.Values.ContainsKey($"nodeName_{culture}") ? source.Values[$"nodeName_{culture}"] : target.Name;

View File

@@ -8,19 +8,22 @@ namespace Umbraco.Web.Search
public interface IUmbracoTreeSearcherFields
{
/// <summary>
/// Propagate list of searchable fields for all node types
/// The default index fields that are searched on in the back office search for umbraco content entities.
/// </summary>
IEnumerable<string> GetBackOfficeFields();
/// <summary>
/// Propagate list of searchable fields for Members
/// The additional index fields that are searched on in the back office for member entities.
/// </summary>
IEnumerable<string> GetBackOfficeMembersFields();
/// <summary>
/// Propagate list of searchable fields for Media
/// The additional index fields that are searched on in the back office for media entities.
/// </summary>
IEnumerable<string> GetBackOfficeMediaFields();
/// <summary>
/// Propagate list of searchable fields for Documents
/// The additional index fields that are searched on in the back office for document entities.
/// </summary>
IEnumerable<string> GetBackOfficeDocumentFields();
}

View File

@@ -1,28 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Umbraco.Web.Search
{
// TODO: Merge this interface to IUmbracoTreeSearcherFields for v9.
// We should probably make these method make a little more sense when they are combined so have
// a single method for getting fields to search and fields to load for each category.
public interface IUmbracoTreeSearcherFields2 : IUmbracoTreeSearcherFields
{
/// <summary>
/// Set of fields for all node types to be loaded
/// </summary>
ISet<string> GetBackOfficeFieldsToLoad();
/// <summary>
/// Set list of fields for Members to be loaded
/// Additional set list of fields for Members to be loaded
/// </summary>
ISet<string> GetBackOfficeMembersFieldsToLoad();
/// <summary>
/// Set of fields for Media to be loaded
/// Additional set of fields for Media to be loaded
/// </summary>
ISet<string> GetBackOfficeMediaFieldsToLoad();
/// <summary>
/// Set of fields for Documents to be loaded
/// Additional set of fields for Documents to be loaded
/// </summary>
ISet<string> GetBackOfficeDocumentFieldsToLoad();
}

View File

@@ -101,7 +101,9 @@ namespace Umbraco.Web.Search
string type;
var indexName = Constants.UmbracoIndexes.InternalIndexName;
var fields = _umbracoTreeSearcherFields.GetBackOfficeFields().ToList();
ISet<string> fieldsToLoad = null;
ISet<string> fieldsToLoad = _umbracoTreeSearcherFields is IUmbracoTreeSearcherFields2 searcherFields2
? new HashSet<string>(searcherFields2.GetBackOfficeFieldsToLoad())
: null;
// TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string
// manipulation for things like start paths, member types, etc...
@@ -124,7 +126,10 @@ namespace Umbraco.Web.Search
fields.AddRange(_umbracoTreeSearcherFields.GetBackOfficeMembersFields());
if (_umbracoTreeSearcherFields is IUmbracoTreeSearcherFields2 umbracoTreeSearcherFieldMember)
{
fieldsToLoad = umbracoTreeSearcherFieldMember.GetBackOfficeMembersFieldsToLoad();
foreach(var field in umbracoTreeSearcherFieldMember.GetBackOfficeMembersFieldsToLoad())
{
fieldsToLoad.Add(field);
}
}
if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1")
{
@@ -138,9 +143,13 @@ namespace Umbraco.Web.Search
fields.AddRange(_umbracoTreeSearcherFields.GetBackOfficeMediaFields());
if (_umbracoTreeSearcherFields is IUmbracoTreeSearcherFields2 umbracoTreeSearcherFieldsMedia)
{
fieldsToLoad = umbracoTreeSearcherFieldsMedia.GetBackOfficeMediaFieldsToLoad();
foreach (var field in umbracoTreeSearcherFieldsMedia.GetBackOfficeMediaFieldsToLoad())
{
fieldsToLoad.Add(field);
}
}
var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService _appCaches);
var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService, _appCaches);
AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
break;
case UmbracoEntityTypes.Document:
@@ -148,7 +157,10 @@ namespace Umbraco.Web.Search
fields.AddRange(_umbracoTreeSearcherFields.GetBackOfficeDocumentFields());
if (_umbracoTreeSearcherFields is IUmbracoTreeSearcherFields2 umbracoTreeSearcherFieldsDocument)
{
fieldsToLoad = umbracoTreeSearcherFieldsDocument.GetBackOfficeDocumentFieldsToLoad();
foreach (var field in umbracoTreeSearcherFieldsDocument.GetBackOfficeDocumentFieldsToLoad())
{
fieldsToLoad.Add(field);
}
}
var allContentStartNodes = _umbracoContext.Security.CurrentUser.CalculateContentStartNodeIds(_entityService, _appCaches);
AppendPath(sb, UmbracoObjectTypes.Document, allContentStartNodes, searchFrom, ignoreUserStartNodes, _entityService);
@@ -168,7 +180,13 @@ namespace Umbraco.Web.Search
return Enumerable.Empty<SearchResultEntity>();
}
var result = internalSearcher.CreateQuery().NativeQuery(sb.ToString()).SelectFields(fieldsToLoad)
var examineQuery = internalSearcher.CreateQuery().NativeQuery(sb.ToString());
if (fieldsToLoad != null)
{
examineQuery.SelectFields(fieldsToLoad);
}
var result = examineQuery
//only return the number of items specified to read up to the amount of records to fill from 0 -> the number of items on the page requested
.Execute(Convert.ToInt32(pageSize * (pageIndex + 1)));

View File

@@ -1,55 +1,62 @@
using Examine;
using Examine.LuceneEngine.Providers;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Services;
using Umbraco.Examine;
namespace Umbraco.Web.Search
{
public class UmbracoTreeSearcherFields : IUmbracoTreeSearcherFields2
{
private IReadOnlyList<string> _backOfficeFields = new List<string> {"id", "__NodeId", "__Key"};
public IEnumerable<string> GetBackOfficeFields()
private IReadOnlyList<string> _backOfficeFields = new List<string> {"id", LuceneIndex.ItemIdFieldName, UmbracoExamineIndex.NodeKeyFieldName};
private readonly ISet<string> _backOfficeFieldsToLoad = new HashSet<string> { "id", LuceneIndex.ItemIdFieldName, UmbracoExamineIndex.NodeKeyFieldName, "nodeName", UmbracoExamineIndex.IconFieldName, LuceneIndex.CategoryFieldName, "parentID", LuceneIndex.ItemTypeFieldName };
private IReadOnlyList<string> _backOfficeMediaFields = new List<string> { UmbracoExamineIndex.UmbracoFileFieldName };
private readonly ISet<string> _backOfficeMediaFieldsToLoad = new HashSet<string> { UmbracoExamineIndex.UmbracoFileFieldName };
private IReadOnlyList<string> _backOfficeMembersFields = new List<string> { "email", "loginName" };
private readonly ISet<string> _backOfficeMembersFieldsToLoad = new HashSet<string> { "email", "loginName" };
private readonly ISet<string> _backOfficeDocumentFieldsToLoad = new HashSet<string> { UmbracoContentIndex.VariesByCultureFieldName };
private readonly ILocalizationService _localizationService;
public UmbracoTreeSearcherFields(ILocalizationService localizationService)
{
return _backOfficeFields;
_localizationService = localizationService;
}
/// <inheritdoc />
public IEnumerable<string> GetBackOfficeFields() => _backOfficeFields;
private IReadOnlyList<string> _backOfficeMembersFields = new List<string> {"email", "loginName"};
public IEnumerable<string> GetBackOfficeMembersFields()
{
return _backOfficeMembersFields;
}
private IReadOnlyList<string> _backOfficeMediaFields = new List<string> {UmbracoExamineIndex.UmbracoFileFieldName };
public IEnumerable<string> GetBackOfficeMediaFields()
{
return _backOfficeMediaFields;
}
public IEnumerable<string> GetBackOfficeDocumentFields()
{
return Enumerable.Empty<string>();
}
/// <inheritdoc />
public IEnumerable<string> GetBackOfficeMembersFields() => _backOfficeMembersFields;
private readonly ISet<string> _backOfficeFieldsToLoad = new HashSet<string> { "id", "__NodeId", "__Key" };
public ISet<string> GetBackOfficeFieldsToLoad()
{
return _backOfficeFieldsToLoad;
}
/// <inheritdoc />
public IEnumerable<string> GetBackOfficeMediaFields() => _backOfficeMediaFields;
private readonly ISet<string> _backOfficeMembersFieldsToLoad = new HashSet<string> { "id", "__NodeId", "__Key", "email", "loginName" };
public ISet<string> GetBackOfficeMembersFieldsToLoad()
{
return _backOfficeMembersFieldsToLoad;
}
/// <inheritdoc />
public IEnumerable<string> GetBackOfficeDocumentFields() => Enumerable.Empty<string>();
private readonly ISet<string> _backOfficeMediaFieldsToLoad = new HashSet<string> { "id", "__NodeId", "__Key", UmbracoExamineIndex.UmbracoFileFieldName };
public ISet<string> GetBackOfficeMediaFieldsToLoad()
{
return _backOfficeMediaFieldsToLoad;
}
private readonly ISet<string> _backOfficeDocumentFieldsToLoad = new HashSet<string> { "id", "__NodeId", "__Key" };
/// <inheritdoc />
public ISet<string> GetBackOfficeFieldsToLoad() => _backOfficeFieldsToLoad;
/// <inheritdoc />
public ISet<string> GetBackOfficeMembersFieldsToLoad() => _backOfficeMembersFieldsToLoad;
/// <inheritdoc />
public ISet<string> GetBackOfficeMediaFieldsToLoad() => _backOfficeMediaFieldsToLoad;
/// <inheritdoc />
public ISet<string> GetBackOfficeDocumentFieldsToLoad()
{
return _backOfficeDocumentFieldsToLoad;
var fields = _backOfficeDocumentFieldsToLoad;
// We need to load all nodeName_* fields but we won't know those up front so need to get
// all langs (this is cached)
foreach(var field in _localizationService.GetAllLanguages().Select(x => "nodeName_" + x.IsoCode.ToLowerInvariant()))
{
fields.Add(field);
}
return fields;
}
}
}