扩展 Umbraco 后台搜索以搜索自定义属性而不仅仅是标题
Extend Umbraco back office search to search custom proerties not just title
我想做的是能够在后台搜索中输入自定义 属性。例如将 ISBN 放入搜索字段并显示当前结果 returns“未找到任何项目”,因为搜索将仅显示标题节点的结果。
如何启用图中所示的内容搜索来搜索自定义字段中的数据?
数据在内部索引中,我已经检查了索引是否正常工作,如果我通过自定义数据搜索,可以在“检查管理”中看到结果。
解决方案是我用来扩展搜索的
https://dev.to/skttl/how-to-customize-searching-in-umbraco-list-views-1knk
在 App_Code (SearchExtender)
中添加一个新文件
using System.Linq;
using Examine;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Editors;
using Umbraco.Web.Models.ContentEditing;
namespace SearchExtender
{
public class CustomListViewSearchController : ContentController
{
public CustomListViewSearchController(PropertyEditorCollection propertyEditors, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper)
: base(propertyEditors, globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
{
}
public PagedResult<ContentItemBasic<ContentPropertyBasic>> GetChildrenCustom(int id, string includeProperties, int pageNumber = 0, int pageSize = 0, string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, bool orderBySystemField = true, string filter = "", string cultureName = "")
{
// get the parent node, and its doctype alias from the content cache
var parentNode = Services.ContentService.GetById(id);
var parentNodeDocTypeAlias = parentNode != null ? parentNode.ContentType.Alias : null;
// if the parent node is not "books", redirect to the core GetChildren() method
if (parentNode?.ContentType.Alias != "books")
{
return GetChildren(id, includeProperties, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
// if we can't get the InternalIndex, redirect to the core GetChildren() method, but log an error
if (!ExamineManager.Instance.TryGetIndex("InternalIndex", out IIndex index))
{
Logger.Error<CustomListViewSearchController>("Couldn't get InternalIndex for searching products in list view");
return GetChildren(id, includeProperties, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
// find children using Examine
// create search criteria
var searcher = index.GetSearcher();
var searchCriteria = searcher.CreateQuery();
var searchQuery = searchCriteria.Field("parentID", id);
if (!filter.IsNullOrWhiteSpace())
{
searchQuery = searchQuery.And().GroupedOr(new [] { "nodeName", "isbn" }, filter);
}
// do the search, but limit the results to the current page https://shazwazza.com/post/paging-with-examine/
// pageNumber is not zero indexed in this, so just multiply pageSize by pageNumber
var searchResults = searchQuery.Execute(pageSize * pageNumber);
// get the results on the current page
// pageNumber is not zero indexed in this, so subtract 1 from the pageNumber
var totalChildren = searchResults.TotalItemCount;
var pagedResultIds = searchResults.Skip((pageNumber > 0 ? pageNumber - 1 : 0) * pageSize).Select(x => x.Id).Select(x => int.Parse(x)).ToList();
var children = Services.ContentService.GetByIds(pagedResultIds).ToList();
if (totalChildren == 0)
{
return new PagedResult<ContentItemBasic<ContentPropertyBasic>>(0, 0, 0);
}
var pagedResult = new PagedResult<ContentItemBasic<ContentPropertyBasic>>(totalChildren, pageNumber, pageSize);
pagedResult.Items = children.Select(content =>
Mapper.Map<IContent, ContentItemBasic<ContentPropertyBasic>>(content))
.ToList(); // evaluate now
return pagedResult;
}
}
}
更改 /umbraco/backoffice/UmbracoApi/Content/GetChildren 的请求(子节点的默认端点),并将其更改为我新创建的,位于 /umbraco/backoffice/api/CustomListViewSearch/GetChildrenCustom.
这很容易通过添加一个包含这样的拦截器的 js 文件来完成。
将文件添加到 /App_Plugins/CustomListViewSearch/CustomListViewSearch.js
angular.module('umbraco.services').config([
'$httpProvider',
function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
'request': function (request) {
// Redirect any requests for the listview to our custom list view UI
if (request.url.indexOf("backoffice/UmbracoApi/Content/GetChildren?id=") > -1)
request.url = request.url.replace("backoffice/UmbracoApi/Content/GetChildren", "backoffice/api/CustomListViewSearch/GetChildrenCustom");
return request || $q.when(request);
}
};
});
}]);
我的 App_Plugins 文件夹中有一个 package.manifest 文件。
{
"javascript": [
"/App_Plugins/CustomListViewSearch/CustomListViewSearch.js"
]
}
如果节点 Alais 不工作,请确保它在文档类型中设置(文档类型名称最右侧)
我想做的是能够在后台搜索中输入自定义 属性。例如将 ISBN 放入搜索字段并显示当前结果 returns“未找到任何项目”,因为搜索将仅显示标题节点的结果。
如何启用图中所示的内容搜索来搜索自定义字段中的数据?
数据在内部索引中,我已经检查了索引是否正常工作,如果我通过自定义数据搜索,可以在“检查管理”中看到结果。
解决方案是我用来扩展搜索的 https://dev.to/skttl/how-to-customize-searching-in-umbraco-list-views-1knk
在 App_Code (SearchExtender)
中添加一个新文件using System.Linq;
using Examine;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Editors;
using Umbraco.Web.Models.ContentEditing;
namespace SearchExtender
{
public class CustomListViewSearchController : ContentController
{
public CustomListViewSearchController(PropertyEditorCollection propertyEditors, IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper)
: base(propertyEditors, globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
{
}
public PagedResult<ContentItemBasic<ContentPropertyBasic>> GetChildrenCustom(int id, string includeProperties, int pageNumber = 0, int pageSize = 0, string orderBy = "SortOrder", Direction orderDirection = Direction.Ascending, bool orderBySystemField = true, string filter = "", string cultureName = "")
{
// get the parent node, and its doctype alias from the content cache
var parentNode = Services.ContentService.GetById(id);
var parentNodeDocTypeAlias = parentNode != null ? parentNode.ContentType.Alias : null;
// if the parent node is not "books", redirect to the core GetChildren() method
if (parentNode?.ContentType.Alias != "books")
{
return GetChildren(id, includeProperties, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
// if we can't get the InternalIndex, redirect to the core GetChildren() method, but log an error
if (!ExamineManager.Instance.TryGetIndex("InternalIndex", out IIndex index))
{
Logger.Error<CustomListViewSearchController>("Couldn't get InternalIndex for searching products in list view");
return GetChildren(id, includeProperties, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
// find children using Examine
// create search criteria
var searcher = index.GetSearcher();
var searchCriteria = searcher.CreateQuery();
var searchQuery = searchCriteria.Field("parentID", id);
if (!filter.IsNullOrWhiteSpace())
{
searchQuery = searchQuery.And().GroupedOr(new [] { "nodeName", "isbn" }, filter);
}
// do the search, but limit the results to the current page https://shazwazza.com/post/paging-with-examine/
// pageNumber is not zero indexed in this, so just multiply pageSize by pageNumber
var searchResults = searchQuery.Execute(pageSize * pageNumber);
// get the results on the current page
// pageNumber is not zero indexed in this, so subtract 1 from the pageNumber
var totalChildren = searchResults.TotalItemCount;
var pagedResultIds = searchResults.Skip((pageNumber > 0 ? pageNumber - 1 : 0) * pageSize).Select(x => x.Id).Select(x => int.Parse(x)).ToList();
var children = Services.ContentService.GetByIds(pagedResultIds).ToList();
if (totalChildren == 0)
{
return new PagedResult<ContentItemBasic<ContentPropertyBasic>>(0, 0, 0);
}
var pagedResult = new PagedResult<ContentItemBasic<ContentPropertyBasic>>(totalChildren, pageNumber, pageSize);
pagedResult.Items = children.Select(content =>
Mapper.Map<IContent, ContentItemBasic<ContentPropertyBasic>>(content))
.ToList(); // evaluate now
return pagedResult;
}
}
}
更改 /umbraco/backoffice/UmbracoApi/Content/GetChildren 的请求(子节点的默认端点),并将其更改为我新创建的,位于 /umbraco/backoffice/api/CustomListViewSearch/GetChildrenCustom.
这很容易通过添加一个包含这样的拦截器的 js 文件来完成。 将文件添加到 /App_Plugins/CustomListViewSearch/CustomListViewSearch.js
angular.module('umbraco.services').config([
'$httpProvider',
function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
'request': function (request) {
// Redirect any requests for the listview to our custom list view UI
if (request.url.indexOf("backoffice/UmbracoApi/Content/GetChildren?id=") > -1)
request.url = request.url.replace("backoffice/UmbracoApi/Content/GetChildren", "backoffice/api/CustomListViewSearch/GetChildrenCustom");
return request || $q.when(request);
}
};
});
}]);
我的 App_Plugins 文件夹中有一个 package.manifest 文件。
{
"javascript": [
"/App_Plugins/CustomListViewSearch/CustomListViewSearch.js"
]
}
如果节点 Alais 不工作,请确保它在文档类型中设置(文档类型名称最右侧)