Masuit.LuceneEFCore.SearchEngine_long 1.0.0-alpha1

This is a prerelease version of Masuit.LuceneEFCore.SearchEngine_long.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Masuit.LuceneEFCore.SearchEngine_long --version 1.0.0-alpha1
NuGet\Install-Package Masuit.LuceneEFCore.SearchEngine_long -Version 1.0.0-alpha1
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="Masuit.LuceneEFCore.SearchEngine_long" Version="1.0.0-alpha1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Masuit.LuceneEFCore.SearchEngine_long --version 1.0.0-alpha1
#r "nuget: Masuit.LuceneEFCore.SearchEngine_long, 1.0.0-alpha1"
#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.
// Install Masuit.LuceneEFCore.SearchEngine_long as a Cake Addin
#addin nuget:?package=Masuit.LuceneEFCore.SearchEngine_long&version=1.0.0-alpha1&prerelease

// Install Masuit.LuceneEFCore.SearchEngine_long as a Cake Tool
#tool nuget:?package=Masuit.LuceneEFCore.SearchEngine_long&version=1.0.0-alpha1&prerelease

基于EntityFrameworkCore和Lucene.NET实现的全文检索搜索引擎

基于EntityFrameworkCore和Lucene.NET实现的全文检索搜索引擎,可轻松实现高性能的全文检索。可以轻松应用于任何基于EntityFrameworkCore的实体框架数据库。

快速开始

EntityFrameworkCore基架搭建

新建项目,并安装EntityFrameworkCore相关库以及全文检索包:

Install-Package Masuit.LuceneEFCore.SearchEngine_int
#根据你的项目情况,选择对应的后缀版本,提供了4个主键版本的库,后缀为int的代表主键是基于int自增类型的,后缀为Guid的代表主键是基于Guid自增类型的...

按照套路我们需要首先搭建好EntityFrameworkCore的基架,即数据库上下文和实体对象;

准备数据库上下文对象:

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options){}
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
    }
    public virtual DbSet<Post> Post { get; set; }
}

准备实体对象,这里开始需要注意了,要想这个库的数据被全文检索,需要符合两个条件: 1.实体必须继承自LuceneIndexableBaseEntity; 2.需要被检索的字段需要被LuceneIndexAttribute所标记。

/// <summary>
/// 文章
/// </summary>
[Table("Post")]
public class Post : LuceneIndexableBaseEntity
{
    public Post()
    {
        PostDate = DateTime.Now;
    }

    /// <summary>
    /// 标题
    /// </summary>
    [Required(ErrorMessage = "文章标题不能为空!"), LuceneIndex]
    public string Title { get; set; }

    /// <summary>
    /// 作者
    /// </summary>
    [Required, MaxLength(24, ErrorMessage = "作者名最长支持24个字符!"), LuceneIndex]
    public string Author { get; set; }

    /// <summary>
    /// 内容
    /// </summary>
    [Required(ErrorMessage = "文章内容不能为空!"), LuceneIndex(IsHtml = true)]
    public string Content { get; set; }

    /// <summary>
    /// 发表时间
    /// </summary>
    public DateTime PostDate { get; set; }

    /// <summary>
    /// 作者邮箱
    /// </summary>
    [Required(ErrorMessage = "作者邮箱不能为空!"), LuceneIndex]
    public string Email { get; set; }

    /// <summary>
    /// 标签
    /// </summary>
    [StringLength(256, ErrorMessage = "标签最大允许255个字符"), LuceneIndex]
    public string Label { get; set; }

    /// <summary>
    /// 文章关键词
    /// </summary>
    [StringLength(256, ErrorMessage = "文章关键词最大允许255个字符"), LuceneIndex]
    public string Keyword { get; set; }

}

LuceneIndexAttribute对应的4个自定义参数: 1.Name:自定义索引字段名,默认为空; 2.Index:索引行为,默认为Field.Index.ANALYZED; 3.Store:是否被存储到索引库,默认为Field.Store.YES; 4.IsHtml:是否是html,默认为false,若标记为true,则在索引解析时会先清空其中的html标签。

搜索引擎配置

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddDbContext<DataContext>(db =>
    {
        db.UseSqlServer("Data Source=.;Initial Catalog=MyBlogs;Integrated Security=True");
    });// 配置数据库上下文
    services.AddSearchEngine<DataContext>(new LuceneIndexerOptions()
    {
        Path = "lucene"
    });// 依赖注入搜索引擎,并配置索引库路径
    // ...
}

HomeController.cs

[Route("[controller]/[action]")]
public class HomeController : Controller
{
    private readonly ISearchEngine<DataContext> _searchEngine;
    private readonly ILuceneIndexer _luceneIndexer;
    public HomeController(ISearchEngine<DataContext> searchEngine, ILuceneIndexer luceneIndexer)
    {
        _searchEngine = searchEngine;
        _luceneIndexer = luceneIndexer;
    }

    /// <summary>
    /// 搜索
    /// </summary>
    /// <param name="s">关键词</param>
    /// <param name="page">第几页</param>
    /// <param name="size">页大小</param>
    /// <returns></returns>
    [HttpGet]
    public async Task<IActionResult> Index(string s, int page, int size)
    {
        //var result = _searchEngine.ScoredSearch<Post>(new SearchOptions(s, page, size, "Title,Content,Email,Author"));
        var result = _searchEngine.ScoredSearch<Post>(new SearchOptions(s, page, size, typeof(Post)));
        return Ok(result);
    }

    /// <summary>
    /// 创建索引
    /// </summary>
    [HttpGet]
    public void CreateIndex()
    {
        //_searchEngine.CreateIndex();//扫描所有数据表,创建符合条件的库的索引
        _searchEngine.CreateIndex(new List<string>() { nameof(Post) });//创建指定的数据表的索引
    }

    /// <summary>
    /// 添加索引
    /// </summary>
    [HttpPost]
    public void AddIndex(Post p)
    {
        // 添加到数据库并更新索引
        _searchEngine.Context.Post.Add(p);
        _searchEngine.SaveChanges();

        //_luceneIndexer.Add(p); //单纯的只添加索引库
    }

    /// <summary>
    /// 删除索引
    /// </summary>
    [HttpDelete]
    public void DeleteIndex(Post post)
    {
        //从数据库删除并更新索引库
        Post p = _searchEngine.Context.Post.Find(post.Id);
        _searchEngine.Context.Post.Remove(p);
        _searchEngine.SaveChanges();

        //_luceneIndexer.Delete(p);// 单纯的从索引库移除
    }

    /// <summary>
    /// 更新索引库
    /// </summary>
    /// <param name="post"></param>
    [HttpPatch]
    public void UpdateIndex(Post post)
    {
        //从数据库更新并同步索引库
        Post p = _searchEngine.Context.Post.Find(post.Id);
        // update...
        _searchEngine.Context.Post.Update(p);
        _searchEngine.SaveChanges();

        //_luceneIndexer.Update(p);// 单纯的更新索引库
    }
}
关于更新索引

要在执行任何CRUD操作后更新索引,只需从ISearchEngine调用SaveChanges()方法,而不是从DataContext调用SaveChanges()。 这才会更新索引,然后会自动调用DataContexts的SaveChanges()方法。如果直接调用DataContexts的SaveChanges()方法,只会保存到数据库,而不会更新索引库。

关于搜索结果

搜索返回IScoredSearchResultCollection<T>,其中包括执行搜索所花费的时间,命中总数以及每个包含的对象的结果集以及在搜索中匹配度的数量。

<font color=#f00>特别注意:单元测试中使用内存RAM目录进行索引和搜索,但这仅用于测试目的,真实生产环境应使用物理磁盘的目录。</font>

演示项目

点击这里

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.4 245 11/17/2023
1.2.3 334 12/21/2022
1.2.2 293 12/8/2022
1.2.1.1 298 11/9/2022
1.2.1 347 10/24/2022
1.2.0 385 9/21/2022
1.1.9 383 9/20/2022
1.1.8 420 3/17/2022
1.1.7 440 1/18/2022
1.1.7-beta 165 1/17/2022
1.1.6 289 12/15/2021
1.1.5 341 9/3/2021
1.1.4 376 8/3/2021
1.1.3 335 5/12/2021
1.1.2 346 5/8/2021
1.1.1 378 11/17/2020
1.1.0 413 11/11/2020
1.0.3.5 395 10/12/2020
1.0.3.4 429 10/9/2020
1.0.3.3 506 8/6/2020
1.0.3.2 427 8/4/2020
1.0.2 573 10/20/2019
1.0.1.3 680 2/16/2019
1.0.1.2 690 2/14/2019
1.0.1.1 652 2/11/2019
1.0.1 669 2/10/2019
1.0.0.1 659 2/1/2019
1.0.0-alpha1 494 1/31/2019