目前索引操作及检索查询相关的方法都是内置在项目内的,需要将其提取出来发布成公共类库,这样在业务项目中就可以安装使用了。那么就将项目放到GitHub上并发布成NuGet包吧!
1.发布为NuGet包
1.1.新建项目迁移代码
新建.NET Standard类库项目Muyan.Search,目标框架为.NET Core 3.1,将所有相关代码迁移到项目中并根据代码文件用途重新调整文件结构。
1.2.新增服务入口
为了便于在其他项目中使用,增加类ServiceCollectionExtension用于定义服务注册的入口。
public static class SeviceCollectionExtension
{
public static IServiceCollection AddSearchManager(this IServiceCollection services,SearchManagerConfig config)
{
services.AddSingleton(config);
services.AddSingleton<Lucene.Net.Store.FSDirectory>(Lucene.Net.Store.FSDirectory.Open(config.FacetPath));
services.AddSingleton<Lucene.Net.Store.Directory>(Lucene.Net.Store.FSDirectory.Open(config.DefaultPath));
services.AddSingleton<Lucene.Net.Analysis.Analyzer>(new JieBaAnalyzer(TokenizerMode.Search, config.StopWords));
services.AddTransient<ISearchManager, SearchManager>();
return services;
}
}
1.3.发布NuGet包
打开代码项目的属性界面,在打包项中勾选“在构建时生成NuGet包”并完善相关信息。
重新编译项目,在输出目录中找到.nupkg文件,推送至公网NuGet Gallery。
2.在业务项目中使用
2.1.安装
打开NuGet管理器,搜索Muyan.Search并安装。
我比较习惯使用ABP框架代码项目,ABP项目推荐安装到领域层xxxCore项目,ASP.NET Core项目直接安装到Web层。
也可以通过命令行安装:
Install-Package RunGo.Search
2.2.配置
在引用项目中配置后方可使用。ABP框架项目在xxxWeb项目中配置,配置文件appsetting.json增加项:
//全文检索配置
"Search": {
"DefaultPath": "Lucene/data",
"FacetPath": "Lucene/facet"
},
在Startup启动类中增加配置:
services.AddSearchManager(new SearchManagerConfig()
{
DefaultPath = _appConfiguration["Search:DefaultPath"],
FacetPath = _appConfiguration["Search:FacetPath"]
});
ASP.NET Core项目的配置与上面相同。
2.3.使用
通过构造函数的形式注入依赖,并以接口形式调用。
public class ArchiveManager : DomainService, IArchiveManager
{
private readonly IRepository<Archive, string> _repository;
private readonly ISearchManager _searchManager;
public ArchiveManager(IRepository<Archive, string> repository,ISearchManager searchManager)
{
_repository = repository;
_searchManager = searchManager;
}
在ABP框架项目中的xxCore领域层、xxApplication应用层、xxWeb分布式服务层均能以上述步骤注入依赖并使用。
2.4.与实体关联
为需要创建索引的实体成员添加Index属性标签。
/// <summary>
/// 文号
/// </summary>
[Index(FieldName = "TitleNo", FieldType = FieldDataType.Text,IsStore = Field.Store.YES)]
public virtual string TitleNo { get; set; }
/// <summary>
/// 年份
/// </summary>
[Index(FieldName = "Year", FieldType = FieldDataType.Facet, IsStore = Field.Store.YES)]
public virtual string Year { get; set; }
/// <summary>
/// 文件题名
/// </summary>
[Index(FieldName = "ArchiveName", FieldType = FieldDataType.Text, IsStore = Field.Store.YES)]
public virtual string ArchiveName { get; set; }
注意:实体应实现接口IEntity,其接口成员仅有string Id {get;set;}
2.5.创建索引
为了避免索引操作与实体操作过度参杂,需要手动添加代码来实现索引操作。
public string CreateIndex()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int i = 0;
List<Archive> entities = _repository.GetAllList(t => t.IsDeleted == false);
foreach (var entity in entities)
{
_searchManager.CreateIndexByEntity(entity,true,false);
i++;
}
stopwatch.Stop();
var t = stopwatch.ElapsedMilliseconds;
return string.Format("Num:{0},Time:{1}", i, t);
}
索引检索查询相关操作同理。