Olti
02/12/2025, 1:01 PM__NodeId 1650
__NodeTypeAlias USNPage
__Path -1,2260,1591,1606,1650
__Published y
combinedField icon-layout color-black y ... (includes full text)
mainContent_en-us 0 {"text":"","headingtag":""} {"text":"","headingtag":""} (seems empty)
nodeName 1.3 Vision Mission Leitbild
searchablePath -1 2260 1591 1606 1650
It seems that combinedField contains the text, but I can't access it via item.Value("combinedField").
This is my current search implementation:Olti
02/12/2025, 4:18 PMOlti
02/12/2025, 4:20 PMOlti
02/12/2025, 4:23 PMOlti
02/12/2025, 5:00 PMMike Chambers
02/12/2025, 5:12 PMMike Chambers
02/12/2025, 5:13 PMMike Chambers
02/12/2025, 5:18 PMpublic override IPropertyIndexValueFactory PropertyIndexValueFactory => _tagPropertyIndexValueFactory;
Or other core propertyIndexValueFactories here https://github.com/umbraco/Umbraco-CMS/tree/contrib/src/Umbraco.Core/PropertyEditors
If you can reuse.. or for inspiration.Olti
02/12/2025, 5:38 PMJemayn
02/13/2025, 12:05 PMOlti
02/13/2025, 12:08 PMusing Umbraco.Cms.Core.Models.PublishedContent;
namespace HunzikerIntranet.HQM.Umbraco.Models
{
public class PagedSearchResult
{
public IEnumerable<IPublishedContent> Results { get; set; }
= Enumerable.Empty<IPublishedContent>();
public long TotalItemCount { get; set; }
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; }
}
}
Olti
02/13/2025, 12:09 PMJemayn
02/13/2025, 12:26 PMitem.Value<string>("combinedField")
as the item in this case is IPublishedContent which is the cached model of the content node. This will instead have a bunch of properties that are put together into the combinedField.
Looping through the properties is a bad idea as they will differ for each pagetype and some of them are probably nested blocklists etc. Instead you can in your searchService you can get the value of your field and have the full content of the combinedField searchfield and then try to find the surrounding text.
In your service you do this:
csharp
var finalSearchList = searchResults
.ToPublishedSearchResults(umbracoContext.PublishedSnapshot.Content)
.Select(x => x.Content);
Which basically converts your searchresult data into IPublishedContent, but in doing so you throw away all of the additional indexed data that doesn't exist on the node but only in the index.
If you for each searchresult retrieved the property with alias combinedField then you would have the text and could use something to find your search term within that text and show it on the page.
The package I mentioned before has this "highlighter helper" which can take the full text of the field, the search term and the length of your summary and then give you a summary centered around the searchterm:
https://github.com/skttl/umbraco-fulltextsearch8/blob/v5/dev/src/Our.Umbraco.FullTextSearch/Helpers/Highlighter.csOlti
02/13/2025, 12:33 PMOlti
02/13/2025, 12:34 PMOlti
02/13/2025, 1:10 PMOlti
02/13/2025, 1:11 PMOlti
02/13/2025, 1:24 PMOlti
02/13/2025, 1:24 PMMike Chambers
02/13/2025, 2:25 PMcsharp
using Examine;
using Examine.Lucene;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Examine;
namespace www.Extensions.Examine
{
public sealed class ConfigureExamineIndexOptions : IConfigureNamedOptions<LuceneDirectoryIndexOptions>
{
public readonly IPublicAccessService _publicAccessService;
[Obsolete("Update when Umbraco Core ContentValueSetValidator is updated")]
private readonly IScopeProvider _scopeProvider;
[Obsolete("Update when Umbraco Core ContentValueSetValidator is updated")]
public ConfigureExamineIndexOptions(IPublicAccessService publicAccessService, IScopeProvider scopeProvider)
{
_publicAccessService = publicAccessService;
_scopeProvider = scopeProvider;
}
[Obsolete("Update when Umbraco Core ContentValueSetValidator is updated")]
public void Configure(string? name, LuceneDirectoryIndexOptions options)
{
switch (name)
{
//NB you need to rebuild the examine index for these changes to take effect
case Constants.UmbracoIndexes.ExternalIndexName:
options.Validator = new ContentValueSetValidator(true, true, _publicAccessService, _scopeProvider);
break;
}
}
public void Configure(LuceneDirectoryIndexOptions options) => throw new NotImplementedException("This is never called and is just part of the interface");
}
public class SearchComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
// Custom Examine configuration
builder.Services.ConfigureOptions<ConfigureExamineIndexOptions>();
}
}
}
Mike Chambers
02/13/2025, 2:25 PMoptions.Validator = new ContentValueSetValidator(true, true, _publicAccessService, _scopeProvider);
changes the external index to include protected nodes.Mike Chambers
02/13/2025, 2:29 PMpublic ContentValueSetValidator(
bool publishedValuesOnly,
bool supportProtectedContent,
IPublicAccessService? publicAccessService,
IScopeProvider? scopeProvider)
Olti
02/14/2025, 10:19 AMOlti
02/14/2025, 11:10 AMusing HunzikerIntranet.HQM.Umbraco.Infrastructure.Configuration;
using HunzikerIntranet.HQM.Umbraco.Interfaces;
using HunzikerIntranet.HQM.Umbraco.Security;
using HunzikerIntranet.HQM.Umbraco.Services;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<AzureAdSettings>(
builder.Configuration.GetSection("AzureAd")
);
builder.Services.AddTransient<ISearchService, SearchService>();
builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.ConfigureAuthenticationMembers(builder.Configuration)
.Build();
WebApplication app = builder.Build();
await app.BootUmbracoAsync();
app.UseUmbraco()
.WithMiddleware(u =>
{
u.UseBackOffice();
u.UseWebsite();
})
.WithEndpoints(u =>
{
u.UseInstallerEndpoints();
u.UseBackOfficeEndpoints();
u.UseWebsiteEndpoints();
});
await app.RunAsync();
and I already tried this "services.AddUnique();" but it didn't work...Mike Chambers
02/14/2025, 11:17 AMOlti
02/14/2025, 11:18 AMMike Chambers
02/14/2025, 11:19 AMMike Chambers
02/14/2025, 11:19 AMOlti
02/14/2025, 11:20 AMOlti
02/14/2025, 11:20 AMMike Chambers
02/14/2025, 11:20 AMOlti
02/14/2025, 11:21 AMOlti
02/14/2025, 11:23 AMOlti
02/14/2025, 11:23 AMOlti
02/14/2025, 11:24 AMMike Chambers
02/14/2025, 11:42 AMrestrict public access
for the entire node?Olti
02/14/2025, 12:14 PMOlti
02/14/2025, 12:42 PMOlti
02/14/2025, 2:08 PMOlti
02/17/2025, 8:18 AM