You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Umbraco:基于EBS的AWS弹性负载均衡下自定义Examine索引实现示例求助

我刚好有过类似的Umbraco自定义Examine索引的实现经验,给你分享几个关键的步骤和示例,帮你确保这个KeywordsIndexer能在AWS EBS的ELB环境下正常工作:

1. 实现自定义DataService(ParagraphKeywordIndexer)

你的配置里指定了dataService="SearchIndexers.ParagraphKeywordIndexer",这个类需要实现ISimpleDataService接口,负责提供要索引的业务数据。以下是适配Umbraco 9+的示例(Umbraco 8的话依赖注入方式略有不同,但核心逻辑一致):

using Examine.LuceneEngine.Providers;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common;

namespace SearchIndexers
{
    public class ParagraphKeywordIndexer : ISimpleDataService
    {
        private readonly UmbracoContextFactory _umbracoContextFactory;
        private readonly IContentService _contentService;

        // 通过构造函数注入Umbraco核心服务
        public ParagraphKeywordIndexer(UmbracoContextFactory umbracoContextFactory, IContentService contentService)
        {
            _umbracoContextFactory = umbracoContextFactory;
            _contentService = contentService;
        }

        public IEnumerable<SimpleDataSet> GetAllData(string indexType)
        {
            // 只处理配置中指定的indexTypes="KeywordIndexItem"
            if (indexType != "KeywordIndexItem") yield break;

            // 这里替换成你实际要索引的内容类型,比如"Paragraph"文档类型
            var targetContents = _contentService.GetContentOfType("Paragraph");

            foreach (var content in targetContents)
            {
                // 提取需要索引的字段,字段别名要和你的Umbraco文档类型字段一致
                var dataSet = new SimpleDataSet
                {
                    NodeDefinition = new NodeDefinition
                    {
                        NodeId = content.Id,
                        NodeTypeAlias = content.ContentType.Alias,
                        ParentId = content.ParentId
                    },
                    RowData = new Dictionary<string, string>
                    {
                        ["id"] = content.Id.ToString(),
                        ["keywords"] = content.Value<string>("keywords") ?? string.Empty,
                        ["title"] = content.Value<string>("pageTitle") ?? string.Empty,
                        ["bodyContent"] = content.Value<string>("bodyText") ?? string.Empty
                    }
                };

                yield return dataSet;
            }
        }
    }
}
2. 完善IndexSet配置(KeywordsIndexSet)

你需要在ExamineIndex.config中添加对应的IndexSet配置,明确要索引的字段和基础规则:

<IndexSet SetName="KeywordsIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/KeywordsIndex/">
  <IndexAttributeFields>
    <add Name="id" />
    <add Name="keywords" />
    <add Name="title" />
    <add Name="bodyContent" />
  </IndexAttributeFields>
  <IncludeNodeTypes>
    <add Name="KeywordIndexItem" />
  </IncludeNodeTypes>
</IndexSet>

因为你配置了TempEnvDirectoryFactory,这个IndexPath会被自动替换为服务器临时目录,刚好适配AWS EBS的弹性环境,不用担心持久化存储的问题。

3. 测试索引构建与搜索功能

后台手动测试

登录Umbraco后台,进入Settings > Examine Management,找到你的KeywordsSearcher,点击Rebuild Index,查看索引状态是否显示成功。如果失败,可查看Umbraco日志(App_Data/Logs目录)排查错误。

代码层面测试

可以写一个简单的搜索服务类,验证索引是否能正常返回结果:

using Examine;
using Umbraco.Cms.Core.Examine;

public class KeywordSearchService
{
    private readonly IExamineManager _examineManager;

    public KeywordSearchService(IExamineManager examineManager)
    {
        _examineManager = examineManager;
    }

    public IEnumerable<ISearchResult> SearchKeywords(string queryText)
    {
        if (!_examineManager.TryGetSearcher("KeywordsSearcher", out var searcher))
        {
            throw new InvalidOperationException("KeywordsSearcher 未找到,请检查Examine配置");
        }

        // 构建搜索条件,这里匹配关键词、标题字段
        var criteria = searcher.CreateSearchCriteria("KeywordIndexItem");
        var filter = criteria.GroupedOr(new[] { "keywords", "title" }, queryText).Compile();
        
        return searcher.Search(filter);
    }
}

你可以在Umbraco的Api控制器或SurfaceController中注入这个服务,调用后查看返回结果是否符合预期。

4. EBS/ELB环境的特殊注意事项
  • 多实例一致性:如果你的Umbraco是多实例部署在ELB下,本地Lucene索引会存在实例间不一致的问题。这种情况推荐改用Examine Cloud,或者替换为AWS OpenSearch这类分布式索引方案;如果是单实例EBS,用TempEnvDirectoryFactory即可,但要确保实例重启后能触发索引自动重建。
  • 权限与存储:确保EBS实例的临时目录有足够的读写权限,Umbraco进程能正常创建和写入索引文件。
  • 自动索引更新:配置内容发布/删除时的自动索引更新,避免手动重建:
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Implement;

public class ContentIndexingHandler : IComponent
{
    private readonly IExamineManager _examineManager;
    private readonly IContentService _contentService;

    public ContentIndexingHandler(IExamineManager examineManager, IContentService contentService)
    {
        _examineManager = examineManager;
        _contentService = contentService;
    }

    public void Initialize()
    {
        ContentService.Published += OnContentPublished;
        ContentService.Deleted += OnContentDeleted;
    }

    private void OnContentPublished(IContentService sender, ContentPublishedEventArgs e)
    {
        var targetItems = e.PublishedEntities.Where(x => x.ContentType.Alias == "Paragraph");
        foreach (var item in targetItems)
        {
            if (_examineManager.TryGetIndex("KeywordsIndexer", out var index))
            {
                index.IndexItem(item);
            }
        }
    }

    private void OnContentDeleted(IContentService sender, ContentDeletedEventArgs e)
    {
        var targetItems = e.DeletedEntities.Where(x => x.ContentType.Alias == "Paragraph");
        foreach (var item in targetItems)
        {
            if (_examineManager.TryGetIndex("KeywordsIndexer", out var index))
            {
                index.DeleteFromIndex(item.Id.ToString());
            }
        }
    }

    public void Terminate()
    {
        ContentService.Published -= OnContentPublished;
        ContentService.Deleted -= OnContentDeleted;
    }
}

最后在Umbraco的Startup.cs中注册这个组件,确保内容变更时自动同步索引。

内容的提问来源于stack exchange,提问作者Town

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:30:15