
CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载Orchard Core 的OrchardCore.Elasticsearch模块为基于 ASP.NET Core 构建的模块化、多租户应用框架提供完整的 Elasticsearch 索引管理能力。本文以官方模块文档为主体结合仓库源码与配套docker-compose.yml系统讲解如何部署 Elasticsearch 集群、在 Orchard Core 中配置连接与认证、通过 Recipe 步骤创建/重建/重置索引、自定义索引数据源、调用api/elasticsearch查询接口并深入对比 Elasticsearch 与 Lucene 在字段映射、索引与存储语义上的差异帮助你快速把 Elasticsearch 全文检索接入 CMS 内容搜索场景。模块概览能做什么OrchardCore.Elasticsearch模块的核心职责是「管理 Elasticsearch 索引」它允许你在 Orchard Core 的管理界面中创建、编辑、重置、重建基于 Elasticsearch 的索引通过 Queries 模块编写 Elasticsearch 查询模板并通过 Web API 或 GraphQL 对外提供检索能力。模块的实现主体位于 src/OrchardCore.Modules/OrchardCore.Elasticsearch界面、控制器、驱动程序与 src/OrchardCore/OrchardCore.Elasticsearch.Core模型、服务、Recipe 步骤、部署步骤所有索引的默认 Analyzer 为standard见 ElasticsearchConstants.cs。Elasticsearch 服务端既可以选用 Elastic Cloud 之类的云服务也可以本地部署on-premises开发测试时还可以用 Docker 快速拉起一套集群。用 Docker Compose 部署 Elasticsearch官方文档在模块目录下附带了一份可直接使用的编排文件 docker-compose.yml它启动一个双节点 Elasticsearch 集群es01、es02镜像版本 9.5.4加一个 Kibana两个 Elasticsearch 节点通过discovery.seed_hosts/cluster.initial_master_nodes组成名为es-docker-cluster的集群各绑定一个命名卷data01、data02持久化索引数据设置bootstrap.memory_locktrue并配合ulimits.memlocksoft/hard 均为-1允许锁定内存避免交换ES_JAVA_OPTS-Xms512m -Xmx512m限定 JVM 堆大小为便于本地开发安全特性被显式关闭xpack.security.enabledfalse、xpack.security.http.ssl.enabledfalse、xpack.security.transport.ssl.enabledfalseElasticsearch 映射宿主机9200端口Kibana 映射5601端口。部署前必读mmap 内核限制Elasticsearch 默认使用mmapfs目录存储索引而操作系统默认的mmap计数上限通常过低会导致out of memory 异常。官方说明见 Elasticsearch 文档的 vm-max-map-count 一节。使用 Docker WSL2 时需要在 Windows 的%userprofile%目录通常是C:\Users\用户名下创建或编辑.wslconfig文件持久化该内核参数[wsl2] kernelCommandLine sysctl.vm.max_map_count262144保存后退出所有 WSL 实例执行wsl --shutdown并重启 WSL然后验证 sysctl vm.max_map_count vm.max_map_count 262144启动步骤将 docker-compose.yml 复制到一个安全位置例如名为Elasticsearch的文件夹在该文件夹中打开终端或命令提示符执行docker-compose up部署 Elasticsearch 容器。提示如果想日后在 Docker Desktop 中一次性删除所有容器请不要把该文件从所在文件夹移走。启动完成后在 Docker Desktop 中应看到类似下图的结果es01、es02 与 kibana 三个容器都在运行失败提示如果你之前使用过较旧版本的elasticsearch镜像升级后可能遇到类似错误The index [.geoip_databases/...] created in version [7.17.5] ... must be marked as read-only using the setting [index.blocks.write] set to [true] before upgrading to 9.0.0.。如果该实例仅用于本地开发官方建议不要按错误提示处理而是直接删除存储数据的卷重新开始先用docker volume ls查看已有卷再执行docker volume rm elasticsearchdocker_data01按实际卷名调整删除 Elasticsearch 使用的数据卷。在 Orchard Core 中启用 Elasticsearch按以下三步即可完成接入在 Shell 配置中添加 Elasticsearch 连接对于OrchardCore.Cms.Web应用即编辑appsettings.json加入OrchardCore_Elasticsearch配置节详见下文「连接配置」配置既可以在全局appsettings.json或其他配置源中设置也支持按租户分别设置参见 Configuration 模块文档。启动 Orchard Core 实例可以用 IDE 或 .NET CLIdotnet run启动。在管理后台的 Features 页面启用 Elasticsearch 功能。连接配置是否有效由源码中的ConfigurationExists()逻辑判定仅当Url非空且能被解析为绝对 URI 时才算已配置见 ElasticsearchConnectionOptions.cs。管理界面中若未配置连接会显示NotConfigured提示视图Views/Admin/NotConfigured.cshtml。Recipe 步骤在部署配方中管理索引Recipe配方允许你在站点初始化或导入数据时通过 JSON 声明式地创建、重置、重建索引。Create Index StepElasticIndexSettings已过时在 Recipe 执行期间可以用ElasticIndexSettings步骤创建 Elasticsearch 索引示例{ steps:[ { name:ElasticIndexSettings, Indices: [ { Search: { AnalyzerName: standard, IndexLatest: false, IndexedContentTypes: [ Article, BlogPost ] } } ] } ] }注意官方建议改用CreateOrUpdateIndexProfile步骤因为ElasticIndexSettings步骤已标记为过时obsolete。推荐方式CreateOrUpdateIndexProfile以下示例演示如何为 Content 类型创建名为BlogPostsES的 Elasticsearch 索引 Profile{ steps:[ { name:CreateOrUpdateIndexProfile, indexes: [ { Name: BlogPostsES, IndexName: blogposts, ProviderName: Elasticsearch, Type: Content, Properties: { ContentIndexMetadata: { IndexLatest: false, IndexedContentTypes: [BlogPosts], Culture: any }, ElasticsearchIndexMetadata: { AnalyzerName: standard, StoreSourceData: true, }, ElasticsearchDefaultQueryMetadata: { QueryAnalyzerName: standard, SearchType: , // The search type can be query_string, custom, or empty for default search type. DefaultQuery: , // When using custom search type, this is the query to use. DefaultSearchFields: [ Content.ContentItem.FullText ] } } } ] } ] }其中的元数据结构与源码模型一一对应ElasticsearchIndexMetadata.cs 中的AnalyzerName、StoreSourceData默认true、IndexMappings以及 ElasticsearchDefaultQueryMetadata.cs 中的QueryAnalyzerName、DefaultQuery、DefaultSearchFields、SearchType。SearchType为空时GetSearchType()会回退到query_string见 ElasticsearchConstants.cs 与 ElasticsearchDefaultQueryMetadata.cs。Reset Elasticsearch Index Stepelastic-index-reset已过时重置索引会从头重新开始索引过程以更新当前内容项但不会删除索引中的已有条目{ steps:[ { name:elastic-index-reset, Indices:[ IndexName1, IndexName2 ] } ] }重置所有索引{ steps:[ { name:elastic-index-reset, IncludeAll:true } ] }注意官方建议改用ResetIndex步骤elastic-index-reset已过时。其实现位于 Recipes/ElasticsearchIndexResetStep.cs。Rebuild Elasticsearch Index Stepelastic-index-rebuild已过时重建索引会删除并重新创建整个索引内容{ steps:[ { name:elastic-index-rebuild, Indices:[ IndexName1, IndexName2 ] } ] }重建所有索引{ steps:[ { name:elastic-index-rebuild, IncludeAll:true } ] }注意官方建议改用RebuildIndex步骤elastic-index-rebuild已过时。其实现位于 Recipes/ElasticsearchIndexRebuildStep.cs。Queries Recipe Step创建 Elasticsearch 查询通过 Queries 的 Recipe 步骤可以直接创建一个 Elasticsearch 查询{ steps:[ { Source: Elasticsearch, Name: RecentBlogPosts, Index: Search, Template: ..., // json encoded query template ReturnContentItems: true } ] }这里的Template是 JSON 编码的查询模板ReturnContentItems决定查询结果是否返回完整内容项而非仅文档字段。索引自定义数据源Indexing custom data索引模块支持多种数据源既可以基于内容项Content Items也可以基于自定义数据Custom Data创建索引。要注册一个新的数据源只需在Startup.cs中添加如下代码services.AddElasticsearchIndexingSource(CustomSource, o { o.DisplayName S[Custom Source in Provider]; o.Description S[Create a Provider index based on custom source.]; });注册后管理界面创建 Elasticsearch 索引时即可选择该自定义源从而把任意业务数据纳入 Elasticsearch 索引。注意S[]本地化字符串需要IStringLocalizer支持在 Orchard Core 服务注册中通常可用。Web API查询内容与文档模块通过 ElasticsearchApiController.cs 暴露两个 REST 接口路由前缀为api/elasticsearch均支持POST与GET动词并受QueryElasticApi权限保护权限定义见 PermissionProvider.cs。api/elasticsearch/content执行指定查询并返回对应的内容项。动词POST、GET。参数示例说明indexNamesearch要查询的索引名称query{ query: { match_all: {} }, size: 10 }表示查询的 JSON 对象parameters{ size: 3}表示查询参数的 JSON 对象从源码看ElasticsearchApiController.cs请求会被转换为一个ElasticsearchQuerySource.SourceName来源的新查询query参数作为ElasticsearchQueryMetadata.Templateparameters反序列化为字典后作为查询参数执行returnContentItems: true时返回内容项。api/elasticsearch/documents执行指定查询并返回对应的 Elasticsearch 文档仅包含存储stored的字段。动词POST、GET。参数示例说明indexNamesearch要查询的索引名称query{ query: { match_all: {} }, size: 10 }表示查询的 JSON 对象parameters{ size: 3}表示查询参数的 JSON 对象Elasticsearch Queries管理界面与查询语法模块提供了一套管理 UI 与 API 用于编写、保存和执行 Elasticsearch 查询Elasticsearch Queries。查询 DSL 遵循 Elasticsearch 官方 Query DSL 语法可在管理后台的 Queries 管理页中选择Elasticsearch作为查询来源对应视图 Views/Query-Elasticsearch.Link.cshtml并在编辑页Views/ElasticQuery.Edit.cshtml中维护模板。相关服务的核心实现见 Services/ElasticsearchQueryService.cs 与 Services/ElasticsearchQuerySource.cs。Elasticsearch 连接配置详解全局 / 租户级连接配置连接配置节名为OrchardCore_Elasticsearch完整示例{ OrchardCore_Elasticsearch: { ConnectionType: SingleNodeConnectionPool, Url: http://localhost, Ports: [ 9200 ], AuthenticationType:Basic, // Supported values are:Basic, ApiKey, Base64ApiKey or KeyIdAndKey ApiKey: , // Required when using ApiKey authentication type Base64ApiKey: , // Required when using Base64ApiKey authentication type CloudId: The cloud id, // Required when using CloudConnectionPool connection type Username: admin, // Required using Basic authentication types Password: admin, // Required using Basic authentication types KeyId: The key id, // Required using KeyIdAndKey authentication types Key: The key, // Required using KeyIdAndKey authentication types CertificateFingerprint: 75:21:E7:92:8F:D5:7A:27:06:38:8E:A4:35:FE:F5:17:D7:37:F4:DF:F0:9A:D2:C0:C4:B6:FF:EE:D1:EA:2B:A7, EnableDebugMode: false, EnableHttpCompression: true, IndexPrefix: , Analyzers: { standard: { type: standard } } } }各字段与源码模型 ElasticsearchConnectionOptions.cs 完全对应字段说明默认值ConnectionType连接池类型见下方枚举SingleNodeConnectionPoolUrl服务器地址无Ports服务器连接端口数组int[]无AuthenticationType认证方式Basic/ApiKey/Base64ApiKey/KeyIdAndKey枚举见 ElasticsearchAuthenticationType.cs无ApiKey使用ApiKey认证时必填空Base64ApiKey使用Base64ApiKey认证时必填空CloudId使用CloudConnectionPool连接类型时必填Elastic Cloud 的 Cloud ID空Username/Password使用Basic认证时必填空KeyId/Key使用KeyIdAndKey认证时必填空CertificateFingerprint服务器证书指纹HTTPS/安全连接场景空EnableDebugMode是否开启调试模式可输出更详细的请求/响应调试信息falseEnableHttpCompression是否启用 HTTP 压缩true源码中属性初始化值IndexPrefix索引名前缀对应 ElasticsearchOptions.cs 中的IndexPrefix空Analyzers可用的分析器字典JsonObject 值仅standard连接类型Connection Type源码枚举 ElasticsearchConnectionType.cs 定义了 5 种连接池类型对应 Elasticsearch .NET 客户端7.17 系列的官方连接池文档SingleNodeConnectionPool单节点连接池适用于单点部署CloudConnectionPoolElastic Cloud 托管连接池此时不需要配置CertificateFingerprint文档明确注明StaticConnectionPool静态连接池节点列表固定SniffingConnectionPool嗅探连接池客户端自动发现集群节点StickyConnectionPool粘性连接池优先复用同一节点。各连接类型的详细文档与示例可参考官方 Elasticsearch 客户端连接池文档connection pooling。索引编辑设置Indexing settings在管理后台的 Index Management 页面Search Indexing编辑基于 Elasticsearch 的索引时可以同时配置通用索引设置与 Elasticsearch 特有设置。Elasticsearch 特有设置包括Query analyzer查询分析器执行查询时使用的分析器默认使用standard如果注册了其他分析器也可以选用。对应ElasticsearchDefaultQueryMetadata.QueryAnalyzerName为空时回退到standard见 ElasticsearchIndexMetadata.cs。Search type搜索类型决定索引的检索方式Multi-Match Query默认使用 Elasticsearch 的multi_match查询在多个配置字段上检索Query String Query使用query_string查询支持更复杂的查询语法Custom Query自定义查询为每次搜索请求定义自定义 Elasticsearch 查询支持 Liquid 模板用{{ term }}占位符代表用户输入的搜索词。下面是一个使用**搜索高亮search highlights**的自定义查询示例{ query: { multi_match: { fields: [ Content.ContentItem.FullText ], query: {{ term }}, fuzziness: AUTO } }, highlight: { pre_tags: [ span stylebackground-color: #FFF3CD; ], post_tags: [ /span ], fields: { Content.ContentItem.FullText: { fragment_size: 150, number_of_fragments: 3 } } } }启用该功能后Elasticsearch 会把命中的片段用span classsearch-highlightHTML 标签包装返回进而可以在 Search 模块或其他组件中展示与搜索词直接匹配的更相关内容。注意高亮请求只有在内容项确实存储在 Elasticsearch 服务中时才有效——即索引设置中的 Store Source Data 复选框被勾选对应ElasticsearchIndexMetadata.StoreSourceData true源码默认值即为true。Elasticsearch Analyzers分析器自 1.6 版本起模块支持 Elasticsearch 内置分析器与自定义分析器。默认只启用standard分析器你可以通过修改appsettings.jsonConfiguration 模块文档启用任意内置或自定义分析器。例如启用内置的stop与standard{ OrchardCore_Elasticsearch: { Analyzers: { standard: { type: standard }, stop: { type: stop } } } }也可以在同一配置节中定义自定义分析器。下面的示例启用了standard分析器、自定义了stop分析器指定停用词列表并创建了一个名为english_analyzer的自定义分析器type: custom由 tokenizer filter char_filter 组合而成{ OrchardCore_Elasticsearch: { Analyzers: { standard: { type: standard }, stop: { type: stop, stopwords: [ a, the, and, or ] }, english_analyzer: { type: custom, tokenizer: standard, filter: [ lowercase, stop ], char_filter: [ html_strip ] } } } }这些分析器声明会进入 ElasticsearchOptions.Analyzers 字典供索引创建与查询执行时使用。Elasticsearch Token-Filters分词过滤器自 2.1 版本起还可以在 Elasticsearch 配置中定义自定义分词过滤器token filters。例如创建一个名为english_stop的过滤器使用_english_预置停用词集并让新的自定义分析器my_new_analyzer引用它{ OrchardCore_Elasticsearch: { TokenFilters: { english_stop: { type: stop, stopwords: _english_ } }, Analyzers: { my_new_analyzer: { type: custom, tokenizer: standard, filter: [ english_stop ] } } } }在该示例中english_stop过滤器负责移除英文停用词my_new_analyzer则用标准分词器配合english_stop过滤器处理文本。TokenFilters同样进入 ElasticsearchOptions.TokenFilters 字典。Elasticsearch 与 Lucene 模块的对比两个模块互补可以同时启用。Lucene 模块基于 Lucene.NET但其功能完整度不及 Elasticsearch 模块由于 Lucene.NET 实现的是较旧版本的 Lucene两个模块的实现会存在差异不过最基本的查询类型两者都支持。关键差异点返回字段Lucene 模块的查询永远只返回stored字段而 Elasticsearch 模块可以设置为只返回特定字段或返回完整的源数据_source。例如下面的查询只从 Elasticsearch 返回指定字段{ query: { match_all: { } }, fields: [ ContentItemId.keyword, ContentItemVersionId.keyword ], _source: false }源数据存储Elasticsearch 索引设置决定是否存储 source 数据默认存储StoreSourceData默认true。自动映射Elasticsearch 会基于 CLR 类型做自动映射——所有映射为 string 的数据字段会同时成为text和keyword。例如Content.ContentItem.DisplayText会映射为text字段而Content.ContentItem.DisplayText.keyword会成为keyword字段供精确值查询使用。字段类型差异Lucene 允许显式地store一个字段或将其设为keywordElasticsearch 目前不受 ContentField 索引设置中stored/keyword选项的影响未来可能通过手动映射实现。因此同一字段名在两个模块中可能出现 Lucene 是text而 Elasticsearch 是keyword的情况查询时需要按实际类型调整查询写法。Indexed已索引与 Stored已存储的语义说一个字段被indexed索引意味着它会经过索引上配置的 Analyzer 解析Elasticsearch 还允许在查询时传递自定义分析器。而stored存储则因上下文而异Elasticsearch 会把传入的原始值存储在索引的_source字段中所有自动映射的字段都不会被单独存储它们只是被索引。Lucene 则在索引设置的 Store source data 开启时存储传入的原始值同时像ContentItemId这类字段天然就是stored字段。为了在 Lucene 中模拟 Elasticsearchkeyword的行为所有传递 string 值的 ContentField 都通过字段名加.keyword后缀的方式提供了等效的StringField。Lucene 与 Elasticsearch 字符串类型对比表LuceneElasticsearch说明存储时查询类型StringFieldKeyword被索引但不分词整个值作为单个 token 索引原始值与索引值精确值term-level查询因为按单个 token 索引TextFieldText被索引且分词不带 term vectors原始值与索引值全文full-text / analyzed查询StoredField通过映射配置存储在_source中包含原始值不分析原始值精确值term-level查询小结OrchardCore.Elasticsearch模块把 Elasticsearch 的部署、连接、索引生命周期管理、查询定义与对外 API 完整地整合进 Orchard CoreRecipe 步骤支持声明式创建/重置/重建索引api/elasticsearch/content与api/elasticsearch/documents提供开箱即用的检索端点Analyzers/TokenFilters配置与索引内搜索类型Multi-Match / Query String / Custom Liquid 高亮则让全文检索行为高度可定制。动手实践时建议从模块目录自带的 docker-compose.yml 起步注意先配置 WSL2 的vm.max_map_count再对照本模块的核心源码OrchardCore.Elasticsearch.Core 与 OrchardCore.Elasticsearch 模块逐步深入。赞分享CMS后端Web框架【免费下载链接】OrchardCoreOrchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.项目地址https://gitcode.com/gh_mirrors/or/OrchardCore点击查看免费下载相关推荐如何在 agno 中让 Agent 按 Pydantic 模型返回结构化输出如何在 agno 中让 Agent 按 Pydantic 模型返回结构化输出 当你用 agno 构建 Agent 时 agent.run 默认返回的是一段自CMS后端Web框架Orchard Core Queries 模块实战指南自定义查询源、SQL 查询、Web API 与 GraphQL 集成Orchard Core Queries 模块实战指南自定义查询源、SQL 查询、Web API 与 GraphQL 集成 Orchard Core 的 QuCMS后端Web框架Ceph RGW Elasticsearch 同步模块elastic-sync-module完全指南元数据索引、查询与配置实战Ceph RGW Elasticsearch 同步模块elastic sync module完全指南元数据索引、查询与配置实战 导读 Elasticsea存储分布式文件系统对象存储后端高可用上一篇深入 go-fuse v2 的 fs 包剖析一个“正确性优先”的高性能 FUSE 文件系统框架下一篇Kazumi高效配置指南5分钟掌握跨平台番剧采集与智能播放创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考