热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elasticsearch集成到ASP.NETCore3.1项目,CRUD操作示例

Elasticsearch集成到ASP.NETCore3.1项目,CRUD操作示例-ElasticSearch简介ElasticSearch是一个开源的搜索引擎,建立在一个全文

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
{
    /// 
    /// 
    /// 
    public class FamousPoemsModel
    {
        /// 
        /// 
        /// 
        public FamousPoemsModel()
        {

        }
        /// 
        /// 
        /// 
        public string Id { get; set; }
        /// 
        /// 作者
        /// 
        [Nest.Keyword]
        public string vcAuthor { get; set; }
        /// 
        /// 内容
        /// 
        [Nest.Keyword]
        public string vcContent { get; set; }
        /// 
        /// 标题
        /// 
        [Nest.Keyword]
        public string vcTitle { get; set; }
        /// 
        /// 创建时间
        /// 
        public DateTime dtCreateTime { get; set; }
        /// 
        /// 更新时间
        /// 
        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
{
    /// 
    /// 
    /// 
    public class FamousPoemsService : IFamousPoemsService, ITransientDependency
    {
        /// 
        /// 
        /// 
        private readonly IEsUpdateService _updateService;
        /// 
        /// 
        /// 
        private readonly IEsClientService _clientService;
        /// 
        /// 
        /// 
        private readonly IEsIndexService _indexService;
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public FamousPoemsService(IEsUpdateService updateService, IEsClientService clientService, IEsIndexService indexService)
        {
            _updateService = updateService;
            _clientService = clientService;
            _indexService = indexService;
        }
        /// 
        /// 删除
        /// 
        /// 
        /// 
        public async Task DeleteAsync(string Id)
        {
            var mustFilters = new List, QueryContainer>>();
            mustFilters.Add(t => t.Match(m => m.Field(f => f.Id).Query(Id)));

            var result = await _clientService.Client.DeleteByQueryAsync(x => x.Index("famouspoemsmodel")
            .Query(q => q.Bool(b => b.Must(mustFilters))));

            return result.Deleted;
        }
        /// 
        /// 根据相关条件获取分页数据
        /// 
        /// 
        /// 
        public async Task> GetPageAsync(ParameterModel dto)
        {
            PageModel pageModel = new PageModel();
            var mustFilters = new List, 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(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(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)data.Documents;
            return pageModel;
        }
        /// 
        /// 新增数据
        /// 
        /// 
        /// 
        public async Task InsertAsync(FamousPoemsModel poems)
        {
            return await _indexService.InsertAsync(poems);
        }
        /// 
        /// 新增批量数据
        /// 
        /// 
        /// 
        public async Task InsertRangeAsync(List poems)
        {
            return await _indexService.InsertRangeAsync(poems);
        }
        /// 
        /// 通过主键局部更新数据
        /// 
        /// 
        /// 
        /// 
        public async Task UpdateAsync(string nId, string vcTitle)
        {
            FamousPoemsModel dto = new FamousPoemsModel();
            dto.vcTitle = vcTitle;
            dto.dtUpdateTime = DateTime.Now;
            var result = _updateService.Update(nId, dto);
            return result.IsValid;
        }
        /// 
        /// 通过条件批量局部更新某个字段数据
        /// 
        /// 
        public async Task UpdateByAuthorAsync(string vcAuthor)
        {
            var mustFilters = new List, QueryContainer>>();
            mustFilters.Add(t => t.Match(m => m.Field(f => f.vcAuthor).Query(vcAuthor)));

            var result = await _clientService.Client.UpdateByQueryAsync(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
{
    /// 
    /// 属性注入
    /// 
    public class PoemsController : ControllerBase
    {
        /// 
        /// 
        /// 
        public IFamousPoemsService famousPoemsService { get; set; }

        /// 
        /// 插入单条数据
        /// 
        /// 
        /// 
        [HttpPost("Poems/InsertAsync")]
        public async Task InsertAsync([FromBody]FamousPoemsModel poems)
        {
            return Content(JsonConvert.SerializeObject(await famousPoemsService.InsertAsync(poems)));
        }
        /// 
        /// 批量插入数据
        /// 
        /// 
        /// 
        [HttpPost("Poems/InsertRangeAsync")]
        public async Task InsertRangeAsync([FromBody]List poems)
        {
            return Content(JsonConvert.SerializeObject(await famousPoemsService.InsertRangeAsync(poems)));
        }
        /// 
        /// 
        /// 
        /// 
        /// 
        [HttpPost("Poems/DeleteAsync")]
        public async Task DeleteAsync(string Id)
        {
            return Content(JsonConvert.SerializeObject(await famousPoemsService.DeleteAsync(Id)));
        }
        /// 
        /// 更新
        /// 
        /// 
        /// 
        /// 
        [HttpPost("Poems/UpdateAsync")]
        public async Task UpdateAsync(string Id, string vcTitle)
        {
            return Content(JsonConvert.SerializeObject(await famousPoemsService.UpdateAsync(Id, vcTitle)));
        }
        /// 
        /// 批量更新
        /// 
        /// 
        /// 
        [HttpPost("Poems/UpdateByAuthorAsync")]
        public async Task UpdateByAuthorAsync(string vcAuthor)
        {
           
            return Content(JsonConvert.SerializeObject(await famousPoemsService.UpdateByAuthorAsync(vcAuthor)));
        }
        /// 
        /// 根据相关条件获取分页数据
        /// 
        /// 
        /// 
        [ProducesResponseType(typeof(FamousPoemsModel), 200)]
        [HttpPost("Poems/GetPageAsync")]
        public async Task 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


推荐阅读
  • Spring Cloud因其强大的功能和灵活性,被誉为开发分布式系统的‘一站式’解决方案。它不仅简化了分布式系统中的常见模式实现,还被广泛应用于企业级生产环境中。本书内容详实,覆盖了从微服务基础到Spring Cloud的高级应用,适合各层次的开发者。 ... [详细]
  • 构建Filebeat-Kafka-Logstash-ElasticSearch-Kibana日志收集体系
    本文介绍了如何使用Filebeat、Kafka、Logstash、ElasticSearch和Kibana构建一个高效、可扩展的日志收集与分析系统。各组件分别承担不同的职责,确保日志数据能够被有效收集、处理、存储及可视化。 ... [详细]
  • 本文介绍了Elasticsearch (ES),这是一个基于Java开发的开源全文搜索引擎。ES通过JSON接口提供服务,支持分布式集群管理和索引功能,特别适合大规模数据的快速搜索与分析。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 58同城的Elasticsearch应用与平台构建实践
    本文由58同城高级架构师于伯伟分享,由陈树昌编辑整理,内容源自DataFunTalk。文章探讨了Elasticsearch作为分布式搜索和分析引擎的应用,特别是在58同城的实施案例,包括集群优化、典型应用实例及自动化平台建设等方面。 ... [详细]
  • Elasticsearch排序机制详解
    本文深入探讨了Elasticsearch中的排序功能,包括相关性排序、字段值排序、多级排序及字符串和多值字段的排序策略,旨在帮助读者更好地理解和优化搜索结果。 ... [详细]
  • 本文介绍了Elasticsearch的基本概念,包括集群、节点、分片和副本的定义,并详细解释了如何执行文档和索引的CRUD操作。同时,文章还探讨了Elasticsearch与传统关系型数据库MySQL之间的对应关系,以及倒排索引的工作原理。 ... [详细]
  • 本文探讨了为何采用RESTful架构及其优势,特别是在现代Web应用开发中的重要性。通过前后端分离和统一接口设计,RESTful API能够提高开发效率,支持多种客户端,并简化维护。 ... [详细]
  • 构建高性能Feed流系统的设计指南
    随着移动互联网的发展,Feed流系统成为了众多社交应用的核心组成部分。本文将深入探讨如何设计一个高效、稳定的Feed流系统,涵盖从基础架构到高级特性的各个方面。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 本文深入解析了Elasticsearch写入与查询的底层机制。在数据写入过程中,首先会将数据暂存至内存缓冲区,在此阶段数据尚不可被搜索。同时,为了保证数据的持久性和可靠性,系统会将这些数据同步记录到事务日志(translog)中。当内存缓冲区接近满载时,系统会触发刷新操作,将缓冲区中的数据写入到磁盘上的段文件中,从而使其可被搜索。此外,文章还探讨了查询过程中涉及的索引分片、倒排索引等关键技术,为读者提供了全面的技术理解。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 探讨了小型企业在构建安全网络和软件时所面临的挑战和机遇。本文介绍了如何通过合理的方法和工具,确保小型企业能够有效提升其软件的安全性,从而保护客户数据并增强市场竞争力。 ... [详细]
  • 本文简要介绍了如何使用 Python Elasticsearch DSL 进行基本和高级查询,包括连接 Elasticsearch、执行简单和复杂查询、聚合、排序及分页等。 ... [详细]
  • 本文详细介绍了Elasticsearch中的分页查询机制,包括基本的分页查询流程、'from-size'浅分页与'scroll'深分页的区别及应用场景,以及两者在性能上的对比。 ... [详细]
author-avatar
杨仕卫123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有