Bitzsoft.Integrations.Search.Lucene
1.0.0-alpha.10
dotnet add package Bitzsoft.Integrations.Search.Lucene --version 1.0.0-alpha.10
NuGet\Install-Package Bitzsoft.Integrations.Search.Lucene -Version 1.0.0-alpha.10
<PackageReference Include="Bitzsoft.Integrations.Search.Lucene" Version="1.0.0-alpha.10" />
<PackageVersion Include="Bitzsoft.Integrations.Search.Lucene" Version="1.0.0-alpha.10" />
<PackageReference Include="Bitzsoft.Integrations.Search.Lucene" />
paket add Bitzsoft.Integrations.Search.Lucene --version 1.0.0-alpha.10
#r "nuget: Bitzsoft.Integrations.Search.Lucene, 1.0.0-alpha.10"
#:package Bitzsoft.Integrations.Search.Lucene@1.0.0-alpha.10
#addin nuget:?package=Bitzsoft.Integrations.Search.Lucene&version=1.0.0-alpha.10&prerelease
#tool nuget:?package=Bitzsoft.Integrations.Search.Lucene&version=1.0.0-alpha.10&prerelease
Bitzsoft.Integrations.Search.Lucene
Lucene.NET 全文检索引擎实现 — 拼音分词、NGram、索引生命周期、三段式检索编排。
功能特性
- 拼音分词器:
PinyinConverter(中文→拼音转换、多音字笛卡尔积全拼、首字母缩写)+PinyinNameDetector(贪婪最长音节匹配、姓在前/姓在后/复姓三种姓名结构识别),底层数据为 416 个标准音节 + 120 个高频姓氏 - 智能多语言分析器:
SmartTextAnalyzer检测中文/拼音/拉丁/英文人名/中英混合 6 种语言类型,分别走 HMM 分词、StandardAnalyzer、姓名变体生成等处理路径 - 弱词过滤体系:LegalSuffix(实体法定后缀剥离,如"有限公司")、OrgWeak(弱组织词,如"集团")、GeoWeak(弱地理词,如"上海",含拼音变体),提升人名召回与降噪
- Analyzer 链:
NGramAnalyzer(bigram 索引)、LowercaseKeywordAnalyzer(整词小写)、SearchPerFieldAnalyzer(按字段路由)、ExtensionFilter(扩展词强制保留为完整 token) - 多字段文档布局:每个文本字段生成 4 个 Lucene 字段(
rawStringField +_searchTextField +_ngramTextField +_superlong超长标记),关键词字段(身份证/统一社会信用代码)仅 StringField - 索引生命周期:
LuceneIndexWriter延迟批量提交(阈值 1000 + 定时 2s + 提交锁串行化),AtomicIndexRebuilder原子目录替换重建(Index → Temp → Bak),全程不中断检索服务 - 三阶段检索编排:构建租户感知分析器 →
SafeQueryBuilder多路径召回 →StreamingConflictCollector流式全量召回 →SearchPipeline按 BusinessId 聚合 - 安全查询构建:
SafeQueryBuilder对每字段同时构建 ngram PhraseQuery + TermQuery + WildcardQuery 三路径 OR 最大化召回,ConstantScoreQuery 包装降低 CPU 开销,clause 爆裂防护(阈值 600 / 上限 1000) - 目录穿越防护:
LuceneIndexDirectoryProvider对 tenantId / directoryName 做白名单校验(仅字母数字下划线连字符),并校验全路径必须位于 basePath 之下 - 多租户隔离:文档写入 TenantId 字段,查询期 MUST 子句按租户过滤
安装
上游兼容性说明:本包使用 Lucene.NET
4.8.0-beta00016。Apache 仍将现代 4.8 版本线标记为 Beta;这里保留 beta00016,是因为更新的 4.8 beta 已把部分传递依赖 提升到不正式支持 .NET 5 的版本。旧稳定版 3.0.3 也不适合作为本实现基础。采用本包前 应把 Lucene 版本、索引格式与回滚方案纳入部署验收,升级后通过重建索引迁移,不要 直接假定旧索引兼容。
.NET CLI
dotnet add package Bitzsoft.Integrations.Search.Lucene
PackageReference
<PackageReference Include="Bitzsoft.Integrations.Search.Lucene" Version="1.0.0" />
配置
appsettings.json
{
"LuceneSearch": {
"BasePath": "/data/lucene"
}
}
| 配置项 | 说明 | 必填 | 默认值 |
|---|---|---|---|
BasePath |
Lucene 索引根目录;目录结构为 BasePath/{tenantId}/{directoryName},重建暂存目录为 directoryNameNew / directoryNameBak / directoryNameTemp |
否 | AppDomain.BaseDirectory/Resources/Lucene |
注册服务
using Bitzsoft.Integrations.Search.Lucene.Indexing;
// 委托配置
builder.Services.AddBitzsoftLuceneSearch(opt =>
{
opt.BasePath = "/data/lucene";
});
从 IConfiguration 节点绑定参数后传入委托:
var section = builder.Configuration.GetSection("LuceneSearch");
builder.Services.AddBitzsoftLuceneSearch(opt =>
{
opt.BasePath = section["BasePath"];
});
引擎注册后,可选注册宿主实现的弱词/停用词/扩展词存储,引擎将自动启用对应的弱词过滤与查询扩展;未注册时使用空集合:
builder.Services.AddScoped<Bitzsoft.Integrations.Search.ISegmentWordStore, MySegmentWordStore>();
builder.Services.AddScoped<Bitzsoft.Integrations.Search.IStopWordProvider, MyStopWordProvider>();
builder.Services.AddScoped<Bitzsoft.Integrations.Search.IExtensionWordProvider, MyExtensionWordProvider>();
注册的服务生命周期:LuceneIndexWriter / LuceneSearchExecutor / AtomicIndexRebuilder / SafeQueryBuilder 为单例(进程级资源),ISearchEngine 为 Scoped(按请求构建含租户弱词的分析器)。
使用示例
写入与删除文档(实时增量)
using Bitzsoft.Integrations.Search;
public sealed class ConflictIndexService(ISearchEngine engine)
{
public Task UpsertAsync(string caseId, string tenantId, string name, string foreignName,
CancellationToken ct)
=> engine.UpsertAsync(
indexKey: "conflict",
tenantId: tenantId,
documentId: caseId,
fields: new Dictionary<string, string?>
{
["Name"] = name,
["ForeignName"] = foreignName,
["EntityType"] = "CaseMatter"
},
cancellationToken: ct);
public Task DeleteAsync(string caseId, string tenantId, CancellationToken ct)
=> engine.DeleteAsync("conflict", tenantId, caseId, ct);
}
有效的
indexKey值:"conflict"(利冲索引)、"keyword-search"(关键字检索索引)。
全量重建索引(原子替换,不中断服务)
public sealed class RebuildService(ISearchEngine engine, ISearchIndexDataSource dataSource)
{
public async Task<RebuildResult> RebuildAsync(string tenantId, CancellationToken ct)
{
// keyset 分页写入 → 提交 → 原子目录替换(IndexNew → Index,旧索引移至 IndexBak)
var result = await engine.RebuildAsync("conflict", tenantId, dataSource, ct);
Console.WriteLine($"已处理 {result.ProcessedCount}/{result.TotalCount},完成={result.Completed}");
return result;
}
}
三段式检索(利冲审查)
public sealed class ConflictSearchService(ISearchEngine engine)
{
public async Task<IReadOnlyList<SearchHitItem>> SearchAsync(
string tenantId, string keyword, CancellationToken ct)
{
var input = new SearchPerformInput
{
IndexKey = "conflict",
TenantId = tenantId,
BusinessName = "ConflictCheck",
Query = new SearchQueryContext
{
// 字段 → 关键字映射驱动多路径召回
SearchFieldWordsDict = new()
{
["Name"] = new() { keyword },
["FormerName"] = new() { keyword }
},
Mode = SearchMode.Fuzzy, // ngram 快速路径 + wildcard 回退
MultiFieldCombineMode = FieldCombineMode.Should // 多字段 OR
},
Filter = new SearchFilterContext
{
ExcludeSourceBusinessId = true, // 排除检索来源自身
ExcludePartyCategories = { "ThirdParty" } // 排除第三方
},
Rule = new SearchRuleContext
{
Scenario = SearchScenario.ProcessRoleOpposing,
Categories = new PartyCategories
{
OurPartyCategories = { "Client" },
OppositePartyCategories = { "Opponent" },
ThirdPartyCategories = { "ThirdParty" }
}
}
};
var output = await engine.SearchAsync(input, ct);
// 结果已按 HitLevel 降序:3=红(我方 vs 对方)、2=黄、1=绿、0=无
return output.Hits;
}
}
索引统计
var stats = await engine.GetStatisticsAsync("conflict", tenantId, ct);
Console.WriteLine($"当前文档总数: {stats.DocumentCount}");
核心类型一览
| 类型 | 说明 |
|---|---|
LuceneSearchEngine |
ISearchEngine 实现,编排索引全生命周期与三段式检索 |
LuceneSearchOptions |
DI 注册选项(BasePath) |
LuceneIndexWriter |
索引写入器,按 directoryName+tenantId 实例化 IndexWriter,延迟批量提交 |
LuceneIndexDirectoryProvider |
索引目录路径解析器,含目录穿越防护 |
AtomicIndexRebuilder |
原子索引重建器(目录替换策略) |
LuceneSearchExecutor |
索引搜索执行器,管理 SearcherManager 生命周期 |
SafeQueryBuilder |
安全查询构建器(多路径召回 + 拼音扩展 + clause 爆裂防护) |
StreamingConflictCollector |
流式全量召回 Collector(利冲专用,零堆分配 CandidateDoc) |
LuceneDocumentBuilder |
文档构建器(4 字段布局:raw/_search/_ngram/_superlong) |
FieldNames |
Lucene 索引标准字段名约定 |
SmartTextAnalyzer |
智能多语言文本分析器(含弱词过滤体系) |
NGramAnalyzer |
bigram 二元语法分析器 |
LowercaseKeywordAnalyzer |
整词小写分析器(关键词字段精确匹配) |
SearchPerFieldAnalyzer |
按字段路由的分析器包装器 |
NGramTokenFilter / ExtensionFilter |
N-gram 过滤器 / 扩展词过滤器 |
PinyinConverter |
中文与拼音转换工具(字符级字典查找) |
PinyinNameDetector |
拼音姓名识别器(贪婪音节匹配 + 姓名结构识别) |
PinyinSyllables |
拼音音节表(416 音节)+ 常见姓氏表(120 个) |
LanguageType |
文本语言类型枚举(Chinese/Pinyin/Latin/English/Mixed/Other) |
依赖
| 包 | 说明 |
|---|---|
Bitzsoft.Integrations.Search |
搜索引擎抽象层(接口定义、检索模型、业务规则) |
Lucene.Net |
Lucene.NET 4.8 beta00016 核心库(兼顾 .NET 5 的上游约束) |
Lucene.Net.Analysis.Common |
同版本通用分析器(StandardAnalyzer 等) |
Lucene.Net.Analysis.SmartCn |
同版本中文智能分词(HMMChineseTokenizer) |
PinYinConverterCore |
中文转拼音字典(PinyinConverter 底层) |
Microsoft.Extensions.Logging.Abstractions |
日志抽象 |
相关包
- Bitzsoft.Integrations.Search -- 全文检索引擎抽象层(统一接口定义、三段式检索上下文、业务规则矩阵、弱词过滤抽象)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
-
net10.0
- Bitzsoft.Integrations.Search (>= 1.0.0-alpha.10)
- Lucene.Net (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.Common (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.SmartCn (>= 4.8.0-beta00016)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- PinYinConverterCore (>= 1.0.2)
-
net5.0
- Bitzsoft.Integrations.Search (>= 1.0.0-alpha.10)
- Lucene.Net (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.Common (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.SmartCn (>= 4.8.0-beta00016)
- Microsoft.Extensions.Logging.Abstractions (>= 5.0.0)
- PinYinConverterCore (>= 1.0.2)
-
net8.0
- Bitzsoft.Integrations.Search (>= 1.0.0-alpha.10)
- Lucene.Net (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.Common (>= 4.8.0-beta00016)
- Lucene.Net.Analysis.SmartCn (>= 4.8.0-beta00016)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- PinYinConverterCore (>= 1.0.2)
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.0.0-alpha.10 | 30 | 7/26/2026 |
| 1.0.0-alpha.9 | 58 | 7/12/2026 |
| 1.0.0-alpha.8 | 312 | 7/1/2026 |