zoukankan      html  css  js  c++  java
  • Elasticsearch集成到ASP.NET Core 3.1项目,CRUD操作示例

    ElasticSearch简介

    ElasticSearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库,无论是开源还是私有。

    但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。

    ElasticSearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

    然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

    ● 一个分布式的实时文档存储,每个字段 可以被索引与搜索
    ● 一个分布式实时分析搜索引擎
    ● 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据

    官方客户端在Java、.NET、PHP、Python、Ruby、Nodejs和许多其他语言中都是可用的。根据 DB-Engines 的排名显示,ElasticSearch 是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

    ElasticSearch不支持的场景:

    1、 不支持事务
    2、 不支持多表关联查询业务
    3、不适合频繁更新的业务场景, 读写有一定延时,写入的数据,最快1s能被检索到
    默认情况下每个分片会每秒自动刷新一次,也就是说文档从Index请求到对外可见能够被搜到,最少要1秒钟,网络和CPU再快也不行。这么做是Lucene为了提高写操作的吞吐量而做出的延迟牺牲,当然这个设置是可以手动调整的,但是并不建议你去动它,会极大地影响搜索性能,刷新频率太高也会导致集群陷入瘫痪。不同的应用对实时性的定义并不一样,这取决于需求。

     

    开始ElasticSearch之旅

    1.创建 ASP.NET Core Web API 项目

    创建net Core项目,将其命名为:ElasticSearchDemo,创建项目后,通过NuGet库引入Nest包

     2.添加实体模型

    将 ES.Models目录添加到项目根目录下

    使用以下代码将 FamousPoemsModel类添加到 ES.Models 目录

    using System;
    
    namespace ES.Models
    {
        /// <summary>
        /// 
        /// </summary>
        public class FamousPoemsModel
        {
            /// <summary>
            /// 
            /// </summary>
            public FamousPoemsModel()
            {
    
            }
            /// <summary>
            /// 
            /// </summary>
            public string Id { get; set; }
            /// <summary>
            /// 作者
            /// </summary>
            [Nest.Keyword]
            public string vcAuthor { get; set; }
            /// <summary>
            /// 内容
            /// </summary>
            [Nest.Keyword]
            public string vcContent { get; set; }
            /// <summary>
            /// 标题
            /// </summary>
            [Nest.Keyword]
            public string vcTitle { get; set; }
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime dtCreateTime { get; set; }
            /// <summary>
            /// 更新时间
            /// </summary>
            public DateTime dtUpdateTime { get; set; }
        }
    }

    3.添加配置模型

    appsettings.json 添加以下ElasticSearch配置

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "ElasticSearch": {
        "Uri": "http://es-cn-zvp2asu64001ta726.public.elasticsearch.aliyuncs.com:9200",
        "UserName": "elastic",
        "Password": "es123456@"
      }
    }

    4.创建ES.Business目录,在目录下创建ElasticSearch、IService、Service目录,废话不多说,直接上代码

    using ES.Business.IService;
    using ES.Core;
    using ES.Models;
    using Nest;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ES.Business.Service
    {
        /// <summary>
        /// 
        /// </summary>
        public class FamousPoemsService : IFamousPoemsService, ITransientDependency
        {
            /// <summary>
            /// 
            /// </summary>
            private readonly IEsUpdateService _updateService;
            /// <summary>
            /// 
            /// </summary>
            private readonly IEsClientService _clientService;
            /// <summary>
            /// 
            /// </summary>
            private readonly IEsIndexService _indexService;
            /// <summary>
            /// 
            /// </summary>
            /// <param name="updateService"></param>
            /// <param name="clientService"></param>
            /// <param name="indexService"></param>
            public FamousPoemsService(IEsUpdateService updateService, IEsClientService clientService, IEsIndexService indexService)
            {
                _updateService = updateService;
                _clientService = clientService;
                _indexService = indexService;
            }
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public async Task<long> DeleteAsync(string Id)
            {
                var mustFilters = new List<Func<QueryContainerDescriptor<FamousPoemsModel>, QueryContainer>>();
                mustFilters.Add(t => t.Match(m => m.Field(f => f.Id).Query(Id)));
    
                var result = await _clientService.Client.DeleteByQueryAsync<FamousPoemsModel>(x => x.Index("famouspoemsmodel")
                .Query(q => q.Bool(b => b.Must(mustFilters))));
    
                return result.Deleted;
            }
            /// <summary>
            /// 根据相关条件获取分页数据
            /// </summary>
            /// <param name="dto"></param>
            /// <returns></returns>
            public async Task<PageModel<FamousPoemsModel>> GetPageAsync(ParameterModel dto)
            {
                PageModel<FamousPoemsModel> pageModel = new PageModel<FamousPoemsModel>();
                var mustFilters = new List<Func<QueryContainerDescriptor<FamousPoemsModel>, QueryContainer>>();
    
                if (!string.IsNullOrEmpty(dto.vcTitle))
                {
                    mustFilters.Add(t => t.Match(m => m.Field(f => f.vcTitle).Query(dto.vcTitle)));
                }
    
                if (dto.authors.Count() > 0)
                {
                    mustFilters.Add(t => t.Terms(m => m.Field(f => f.vcAuthor).Terms(dto.authors.ToArray())));
                }
    
                var total = await _clientService.Client.CountAsync<FamousPoemsModel>(x => x.Index("famouspoemsmodel")
                 .Query(q => q.Bool(b => b.Must(mustFilters))));
    
                if (total.Count == 0)
                {
                    return pageModel;
                }
    
                pageModel.nDataCount = Convert.ToInt32(total.Count);
                pageModel.nPageCount = (int)Math.Ceiling((double)pageModel.nDataCount / dto.nPageSize);
                dto.nPageIndex = ((dto.nPageIndex < 1 ? 1 : dto.nPageIndex) - 1) * dto.nPageSize;
    
                var data = await _clientService.Client.SearchAsync<FamousPoemsModel>(x => x.Index("famouspoemsmodel")
         .Query(q => q.Bool(b => b.Must(mustFilters))).Sort(s => s.Ascending(d => d.dtCreateTime)).From(dto.nPageIndex).Size(dto.nPageSize));
    
                pageModel.data = (List<FamousPoemsModel>)data.Documents;
                return pageModel;
            }
            /// <summary>
            /// 新增数据
            /// </summary>
            /// <param name="poems"></param>
            /// <returns></returns>
            public async Task<bool> InsertAsync(FamousPoemsModel poems)
            {
                return await _indexService.InsertAsync(poems);
            }
            /// <summary>
            /// 新增批量数据
            /// </summary>
            /// <param name="poems"></param>
            /// <returns></returns>
            public async Task<bool> InsertRangeAsync(List<FamousPoemsModel> poems)
            {
                return await _indexService.InsertRangeAsync(poems);
            }
            /// <summary>
            /// 通过主键局部更新数据
            /// </summary>
            /// <param name="nId"></param>
            /// <param name="vcTitle"></param>
            /// <returns></returns>
            public async Task<bool> UpdateAsync(string nId, string vcTitle)
            {
                FamousPoemsModel dto = new FamousPoemsModel();
                dto.vcTitle = vcTitle;
                dto.dtUpdateTime = DateTime.Now;
                var result = _updateService.Update<FamousPoemsModel>(nId, dto);
                return result.IsValid;
            }
            /// <summary>
            /// 通过条件批量局部更新某个字段数据
            /// </summary>
            /// <returns></returns>
            public async Task<bool> UpdateByAuthorAsync(string vcAuthor)
            {
                var mustFilters = new List<Func<QueryContainerDescriptor<FamousPoemsModel>, QueryContainer>>();
                mustFilters.Add(t => t.Match(m => m.Field(f => f.vcAuthor).Query(vcAuthor)));
    
                var result = await _clientService.Client.UpdateByQueryAsync<FamousPoemsModel>(q => q.Index("famouspoemsmodel")
       .Query(q => q.Bool(t => t.Must(mustFilters)))
    .Script(script => script.Source("ctx._source.dtUpdateTime=" + DateTime.Now + ";")));
    
                return result.IsValid;
    
            }
        }
    }

    5.将以下代码添加到 Startup.ConfigureServices

              #region ES配置
                services.AddEsService(options =>
                {
                    options.Urls = Configuration["ElasticSearch:Uri"];
                    options.UserName = Configuration["ElasticSearch:UserName"];
                    options.Password = Configuration["ElasticSearch:Password"];
                });
                #endregion

    6.添加控制器

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using ES.Business.IService;
    using ES.Models;
    using ES.Util;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;
    
    namespace ES.Web.Controllers
    {
        /// <summary>
        /// 属性注入
        /// </summary>
        public class PoemsController : ControllerBase
        {
            /// <summary>
            /// 
            /// </summary>
            public IFamousPoemsService famousPoemsService { get; set; }
    
            /// <summary>
            /// 插入单条数据
            /// </summary>
            /// <param name="poems"></param>
            /// <returns></returns>
            [HttpPost("Poems/InsertAsync")]
            public async Task<IActionResult> InsertAsync([FromBody]FamousPoemsModel poems)
            {
                return Content(JsonConvert.SerializeObject(await famousPoemsService.InsertAsync(poems)));
            }
            /// <summary>
            /// 批量插入数据
            /// </summary>
            /// <param name="poems"></param>
            /// <returns></returns>
            [HttpPost("Poems/InsertRangeAsync")]
            public async Task<ActionResult> InsertRangeAsync([FromBody]List<FamousPoemsModel> poems)
            {
                return Content(JsonConvert.SerializeObject(await famousPoemsService.InsertRangeAsync(poems)));
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            [HttpPost("Poems/DeleteAsync")]
            public async Task<ActionResult> DeleteAsync(string Id)
            {
                return Content(JsonConvert.SerializeObject(await famousPoemsService.DeleteAsync(Id)));
            }
            /// <summary>
            /// 更新
            /// </summary>
            /// <param name="Id"></param>
            /// <param name="vcTitle"></param>
            /// <returns></returns>
            [HttpPost("Poems/UpdateAsync")]
            public async Task<ActionResult> UpdateAsync(string Id, string vcTitle)
            {
                return Content(JsonConvert.SerializeObject(await famousPoemsService.UpdateAsync(Id, vcTitle)));
            }
            /// <summary>
            /// 批量更新
            /// </summary>
            /// <param name="vcAuthor"></param>
            /// <returns></returns>
            [HttpPost("Poems/UpdateByAuthorAsync")]
            public async Task<ActionResult> UpdateByAuthorAsync(string vcAuthor)
            {
               
                return Content(JsonConvert.SerializeObject(await famousPoemsService.UpdateByAuthorAsync(vcAuthor)));
            }
            /// <summary>
            /// 根据相关条件获取分页数据
            /// </summary>
            /// <param name="dto"></param>
            /// <returns></returns>
            [ProducesResponseType(typeof(FamousPoemsModel), 200)]
            [HttpPost("Poems/GetPageAsync")]
            public async Task<ActionResult> GetPageAsync([FromBody]ParameterModel dto)
            {
                return Content(JsonConvert.SerializeObject(await famousPoemsService.GetPageAsync(dto)));
            }
        }
    }

    本示例代码gitee地址:https://gitee.com/fan_zhongtuan/elasticsearchdemo.git

    阿里云ElasticSearch新用户0员免费试用地址:https://www.aliyun.com/product/bigdata/elasticsearch

    Elasticsearch官方权威文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html

  • 相关阅读:
    函数,封装
    c++增强c
    Git安装与使用
    Ajax&Jquery
    IntelliJ Idea2018.2,Pycharm20183.2破解教程
    事务&数据库连接池&DBUtils&JSP设计模式
    JSP&EL&JSTL
    Http协议和Servlet
    接收流信息---字符串
    lucene索引库优化一
  • 原文地址:https://www.cnblogs.com/xiaoguli/p/15181186.html
Copyright © 2011-2022 走看看