OctopusEx.SearchCore
1.2.2026.712
dotnet add package OctopusEx.SearchCore --version 1.2.2026.712
NuGet\Install-Package OctopusEx.SearchCore -Version 1.2.2026.712
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OctopusEx.SearchCore" Version="1.2.2026.712" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OctopusEx.SearchCore" Version="1.2.2026.712" />
<PackageReference Include="OctopusEx.SearchCore" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OctopusEx.SearchCore --version 1.2.2026.712
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: OctopusEx.SearchCore, 1.2.2026.712"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OctopusEx.SearchCore@1.2.2026.712
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OctopusEx.SearchCore&version=1.2.2026.712
#tool nuget:?package=OctopusEx.SearchCore&version=1.2.2026.712
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
OctopusUtils
面向中文互联网场景的 .NET 组件库
聚合全文搜索 · 中文分词 · 异步控制台 · 重试机制 · AI 客户端 · Web 脚手架
快速开始 · 功能模块 · 文档 · 更新日志 · 贡献指南
✨ 特性概览
- 🔍 全文搜索引擎:基于 Lucene.NET 4.8,原生中文分词支持,支持模糊搜索、多字段权重、分页排序。
- ✂️ 中文分词:移植自结巴分词,内置 HMM 未登录词识别,支持 TF-IDF / TextRank 关键词提取。
- ⚡ 异步彩色控制台:非阻塞队列写入,内置 Info / Debug / Warn / Error 四级日志,带时间戳前缀。
- 🔄 智能重试机制:同步/异步通用,可配置次数、间隔、回调,一行代码包装任意操作。
- 🤖 AI 客户端:兼容 OpenAI / Llama API,内置会话缓存,支持批量翻译、自动写作等场景。
- 🏗️ Web 脚手架:DDD + CQRS + Repository,自动依赖注入、审计日志、健康检查、Hangfire 一键接入。
📦 快速开始
安装
根据需要选择安装对应包:
# 核心工具(控制台、重试、AI客户端、缓存)
dotnet add package OctopusEx.Tools
# 中文分词
dotnet add package OctopusEx.Segment
# 全文搜索引擎
dotnet add package OctopusEx.SearchCore
# ASP.NET Core Web 脚手架
dotnet add package OctopusEx.WebCore
从源码构建
git clone https://github.com/Fat-Snail/OctopusUtils.git
cd OctopusUtils
dotnet restore && dotnet build
🗂️ 功能模块
Octopus.Tools · netstandard2.0
⚡ 异步彩色控制台 (ConsoleEx)
using Octopus;
// 带时间戳的日志级别输出
ConsoleEx.Info("服务启动成功"); // [INFO] 绿色
ConsoleEx.Debug("用户 ID = 12345"); // [DEBUG] 蓝色
ConsoleEx.Warn("磁盘剩余空间不足 10%"); // [WARN] 黄色
ConsoleEx.Error("数据库连接失败,请检查配置"); // [ERROR] 红色
// 自定义颜色
ConsoleEx.WriteLine("处理完成 ✓", ConsoleColor.Cyan);
// 应用退出前优雅关闭(等待队列清空)
await ConsoleEx.ShutdownAsync(timeout: 3000);
写入操作通过内部
BlockingCollection队列异步消费,不阻塞主线程。
🔄 智能重试 (Utils.RetryMethod)
using Octopus;
// 同步重试(有返回值)
var result = Utils.RetryMethod(
() => FetchDataFromApi(),
maxRetryCount: 5,
sleepTime: 500,
onRetry: (attempt, ex) => ConsoleEx.Warn($"第 {attempt} 次重试: {ex.Message}")
);
// 异步重试(无返回值)
await Utils.RetryMethodAsync(async () =>
{
await UploadFileAsync();
}, maxRetryCount: 3, throwOnFailure: true);
📊 控制台进度条 (ConsoleProgressBar)
using var progress = new ConsoleProgressBar();
for (int i = 0; i <= 100; i++)
{
progress.Report(i / 100.0); // [########--] 80% |
await Task.Delay(50);
}
🤖 AI 客户端 (AIClient)
using Octopus;
// 全局配置(一次即可)
AIClient.SetClientParams(s =>
{
s.ApiDomain = "https://api.openai.com";
s.ApiKey = "sk-...";
s.DefaultModel = "gpt-4o-mini";
});
// 获取客户端(按名称缓存)
var client = AIClient.CreateAiChat("translator");
var response = await client.CreateChatCompletionAsync(
client.CreateNormalRequest(req =>
{
req.Messages = [new() { Role = "user", Content = "将以下文本翻译为英文:你好世界" }];
})
);
Console.WriteLine(response.Choices[0].Message.Content);
🗃️ TTL 缓存 (DictionaryCache)
using NewLife;
var cache = new DictionaryCache<String, UserInfo>
{
Expire = 300, // 300 秒过期
Asynchronous = true // 过期后后台刷新,旧值继续可用
};
var user = cache.GetItem("user:42", key => LoadUserFromDb(key));
Octopus.Segment · netstandard2.1
✂️ 中文分词 (JiebaSegmenter)
using JiebaNet.Segmenter;
var seg = new JiebaSegmenter();
// 精确模式(默认)
var words = seg.Cut("我来到北京清华大学");
// → ["我", "来到", "北京", "清华大学"]
// 搜索引擎模式(更高召回)
var searchWords = seg.CutForSearch("小明硕士毕业于中国科学院");
// → ["小明", "硕士", "毕业", "于", "中国", "科学", "学院", "中国科学院"]
// 动态添加自定义词
seg.AddWord("OctopusUtils", freq: 1000, tag: "eng");
🔑 关键词提取
using JiebaNet.Analyser;
// TF-IDF 提取
var tfidf = new TfidfExtractor();
var keywords = tfidf.ExtractTagsWithWeight(
"此次发布包含多项性能优化和安全修复", topK: 5);
// → [("性能优化", 0.48), ("安全修复", 0.35), ...]
// TextRank 图算法提取(无需语料库)
var textrank = new TextRankExtractor();
var tags = textrank.ExtractTags(article, topK: 10);
Octopus.SearchCore · net10.0
🔍 全文搜索引擎
第一步:定义可索引实体
using Octopus.SearchCore;
public class Article : LuceneIndexableBaseEntity
{
[LuceneIndex] public String Title { get; set; }
[LuceneIndex] public String Content { get; set; }
[LuceneIndex] public String Author { get; set; }
public override Document ToDocument()
{
var doc = new Document();
doc.AddTextField("Title", Title, Field.Store.YES);
doc.AddTextField("Content", Content, Field.Store.NO);
doc.AddStringField("Author", Author, Field.Store.YES);
return doc;
}
}
第二步:注册服务并构建索引
services.AddLuceneSearchEngine<Article>(options =>
{
options.IndexPath = "wwwroot/indexes/article";
});
// 全量建索引
await searchEngine.CreateIndex();
第三步:搜索
// 按关键词搜索,支持 "短语" 和 -排除词
var results = searchEngine.ScoredSearch<Article>(new SearchOptions(
keywords : "人工智能 -广告",
page : 1,
size : 20,
fields : ["Title", "Content"]
));
Console.WriteLine($"共命中 {results.TotalHits} 条,耗时 {results.Elapsed.TotalMilliseconds:F0}ms");
foreach (var item in results.Results)
Console.WriteLine($"[{item.Score:F2}] {item.Entity.Title}");
OctopusEx.WebCore · net10.0
🏗️ 自动依赖注入
// 1. 服务接口继承生命周期接口(推荐方式)
public interface IOrderService : IScopeDependency
{
Task<OrderDto> CreateOrderAsync(CreateOrderRequest request);
}
// 2. 实现类只继承业务接口
public class OrderService : IOrderService
{
public async Task<OrderDto> CreateOrderAsync(CreateOrderRequest request) { ... }
}
// 3. 一行代码开启扫描注册,无需手动 AddScoped
builder.Host.AddUtil();
// OrderService 自动以 IOrderService 注册为 Scoped
🗄️ CRUD 脚手架(Repository + Service + Controller)
// Entity
public class Product : BaseEntity<Int32> { ... }
// Service — 只需重写映射,CRUD 逻辑全部继承
public class ProductService
: CrudServiceBase<Product, Int32, ProductDto, CreateProductDto, UpdateProductDto>
{
protected override ProductDto MapToDto(Product entity) => new() { ... };
protected override Product MapToEntity(CreateProductDto dto) => new() { ... };
protected override Int32 GetEntityId(Product e) => e.Id;
protected override Int32 GetUpdateRequestId(UpdateProductDto dto) => dto.Id;
// 可选:删除前业务校验
protected override async Task<DeleteCheckResult> CanDeleteAsync(Int32 id)
{
var hasOrders = await orderRepo.ExistsAsync(o => o.ProductId == id);
return hasOrders
? DeleteCheckResult.NotAllowed("存在关联订单,无法删除")
: DeleteCheckResult.Allowed();
}
}
// Controller — 七个 REST 端点自动生成
[ApiController, Route("api/products")]
public class ProductController
: CURDControllerBase<Product, Int32, ProductDto, CreateProductDto, UpdateProductDto>
{
public ProductController(IProductService service) : base(service) { }
}
生成的端点:
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/products/{id} |
获取单个 |
GET |
/api/products |
分页列表 |
GET |
/api/products/all |
全量获取 |
POST |
/api/products |
创建 |
PUT |
/api/products/{id} |
更新 |
DELETE |
/api/products/{id} |
删除 |
POST |
/api/products/bulk-delete |
批量删除 |
📋 审计日志 (AuditInterceptor)
// Program.cs — 一行注册,SaveChanges 自动捕获所有变更
builder.Services.AddAuditService(config =>
{
config.GetCurrentUser = sp =>
{
var http = sp.GetRequiredService<IHttpContextAccessor>();
return new AuditUser
{
UserId = http.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier),
UserName = http.HttpContext?.User.Identity?.Name
};
};
});
每次 SaveChangesAsync() 后自动写入:
{
"EntityName": "Product",
"Action": "UPDATE",
"OldValues": { "Price": 99.00 },
"NewValues": { "Price": 129.00 },
"ChangedProperties": ["Price"],
"UserId": "u-001",
"Timestamp": "2026-05-09T10:30:00Z"
}
⏰ 后台任务 (HangfireExtensions)
// 注册(内存存储,零依赖)
builder.Services.AddSimpleHangfire(workerCount: 2);
// 一次性任务
provider.AddBackgroundJob("send-welcome-email", async () =>
await emailService.SendWelcomeAsync(userId));
// 延迟任务
provider.AddDelayedJob("expire-coupon", async () =>
await couponService.ExpireAsync(couponId), delay: TimeSpan.FromHours(24));
// 定时任务(Cron 表达式)
provider.AddRecurringJob("daily-report", async () =>
await reportService.GenerateDailyAsync(), cronExpression: "0 8 * * *");
🏥 健康检查 (HealthCheckExtensions)
// 注册
builder.Services
.AddDatabaseHealthCheck(connectionString, "sqlserver")
.AddExternalApiHealthCheck("payment-gateway", "https://pay.example.com/ping")
.AddCacheHealthCheck("redis", sp => sp.GetRequiredService<IDistributedCache>());
// 映射端点
app.MapHealthCheckEndpoints();
| 端点 | 用途 |
|---|---|
GET /health/ready |
K8s 就绪探针 |
GET /health/live |
K8s 存活探针 |
GET /health/full |
全项检查 |
GET /health |
详细状态(含耗时 / 描述) |
🛡️ 敏感词过滤 (SensitiveWordFilterPlugin)
var filter = new SensitiveWordFilterPlugin(kernel); // kernel 可选,不传则仅词典模式
// 快速检测(ToolGood.Words,毫秒级)
var result1 = filter.DetectSensitiveWords(text);
// AI 语义检测(Semantic Kernel)
var result2 = await filter.DetectSensitiveWordsWithAI(text);
// 综合检测(词典 → AI 兜底)
var result3 = await filter.ComprehensiveDetectSensitiveWords(text);
// 管理词库
filter.SetSensitiveWords(["词1", "词2"]);
filter.AddSensitiveWord("新词");
🏛️ 架构总览
OctopusUtils.sln
│
├── Octopus.Tools [netstandard2.0] 控制台 · 重试 · AI客户端 · 缓存 · 字符串扩展
├── Octopus.Segment [netstandard2.1] 结巴分词 · TF-IDF · TextRank · 词性标注
├── Octopus.SearchCore [net10.0] Lucene.NET 全文搜索 · Tag提取 · 中文分析器
└── OctopusEx.WebCore [net10.0] DDD脚手架 · 自动DI · 审计 · 健康检查 · Hangfire
│
├── Dependency/ 自动依赖注入(生命周期接口 + 程序集扫描)
├── DomainCore/ IRepository · IUnitOfWork · CrudServiceBase · WhereIf
├── Extensions/ ApiUI · Aspire · Audit · Hangfire · HealthCheck
└── Plugins/ SensitiveWordFilterPlugin
WebCore 数据流
HTTP Request
└─► CURDControllerBase 路由 / 统一响应格式
└─► CrudServiceBase 验证 / 生命周期钩子 / DTO映射
└─► IRepository (IQuery + ICommand)
└─► IUnitOfWork.SaveChangesAsync()
└─► AuditInterceptor ──► AuditLog
📖 文档
| 文档 | 说明 |
|---|---|
| CHANGELOG.md | 版本更新日志 |
| REQUIREMENTS.md | 完整功能需求文档 |
| Search.md | 全文搜索使用指南 |
| AIClient.md | AI 客户端使用指南 |
| Google.md | Google Drive 下载指南 |
| ConsoleShow.md | 控制台进度条指南 |
| UnitTest.md | 单元测试工具指南 |
| HUSKY.md | 代码提交质量检查 |
| OctopusEx.WebCore/README.md | Web 脚手架详细文档 |
🗺️ 路线图
查看 roadmap.md 了解后续计划,欢迎通过 Issue 提交建议。
🤝 贡献
欢迎任何形式的贡献!
- Fork 本仓库
- 创建特性分支
git checkout -b feat/your-feature - 提交变更(遵循 Conventional Commits)
- 发起 Pull Request
本项目使用 Husky.NET 在提交时自动格式化代码,首次克隆后运行:
dotnet tool restore
dotnet husky install
📄 许可证
本项目基于 MIT License 开源。
Copyright © 2024–2026 Fatty Coder
如果这个项目对你有帮助,欢迎点个 ⭐ Star 支持一下!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- Lucene.Net.QueryParser (>= 4.8.0-beta00017)
- Microsoft.Extensions.AI.Abstractions (>= 9.5.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.7)
- Microsoft.Extensions.DependencyInjection (>= 10.0.7)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.7)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.7)
- OctopusEx.Segment (>= 1.3.2026.712)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.2026.712 | 114 | 7/12/2026 |
首次发布 net10.0 包;提供 Lucene.NET 中文全文搜索、Jieba 分词、标签提取、内存缓存与依赖注入集成。
