查看原文
其他

.NET API 之如何使用 Elasticsearch 存储文档

DotNet 2022-07-19

↓推荐关注↓

一、什么是 Elasticsearch


Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。


Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。


总之这个数据库可以很灵活的对你存入的数据进行分词并查询,可以灵活的处理字段内容,筛选你想要的数据,更重要的是这个数据库是分布式的,可以减少应为一个数据库down掉而导致的数据丢失。


以下简称Elasticsearch为Es数据库。前言 | Elasticsearch: 权威指南 | Elastic


二、用Nest使用Es数据库


配置Nest


在C# 的环境中,有一个Es的官方拓展包Nest,可以让我们方便快捷的使用上Es数据库。首先在我们新建完项目后,需要在Nuget包管理中给项目安装NEST包。


安装完NEST包之后,需要新建一个Es的配置类EsConfig.cs,这里我们只使用最简单的账号,密码和数据库地址

/// <summary>
/// ES配置类
/// </summary>
public class EsConfig
{
    /// <summary>
    /// 账号
    /// </summary>
    public string username { getset; }
    /// <summary>
    /// 密码
    /// </summary>
    public string password { getset; }
    /// <summary>
    /// ES地址
    /// </summary>
    public string url { getset; }
}

有了配置类之后,需要在程序启动时,对Es进行配置。首先这里先新建一个Es客户端的接口类IElasticsearchClient.cs

/// <summary>
/// ES客户端
/// </summary>
public interface IElasticsearchClient
{
    /// <summary>
    /// 获取ElasticClient
    /// </summary>
    /// <returns></returns>
    ElasticClient GetClient();
    /// <summary>
    /// 指定index获取ElasticClient
    /// </summary>
    /// <param name="indexName"></param>
    /// <returns></returns>
    ElasticClient GetClient(string indexName);
}

在配置对该接口的实现类ElasticsearchClient.cs,在这个实现类中我们使用了IOptions的依赖注入的形式来对配置文件进行配置,这种模式通常适用于API类型项目的配置。

我们也可以使用直接_EsConfig = Configuration.GetSection("EsConfig").Get<EsConfig>();的形式来读取配置文件进行配置

/// <summary>
/// ES客户端
/// </summary>
public class ElasticsearchClient : IElasticsearchClient
{
    public EsConfig _EsConfig;
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="esConfig"></param>
    public ElasticsearchClient(IOptions<EsConfig> esConfig)
    {
        _EsConfig = esConfig.Value;
    }
    /// <summary>
    /// 获取elastic client
    /// </summary>
    /// <returns></returns>
    public ElasticClient GetClient()
    {
        if (_EsConfig == null || _EsConfig.url == null || _EsConfig.url == "")
        {
            throw new Exception("urls can not be null");
        }
        return GetClient(_EsConfig.url, "");
    }
    /// <summary>
    /// 指定index获取ElasticClient
    /// </summary>
    /// <param name="indexName"></param>
    /// <returns></returns>
    public ElasticClient GetClient(string indexName)
    {
        if (_EsConfig == null || _EsConfig.url == null || _EsConfig.url == "")
        {
            throw new Exception("urls can not be null");
        }
        return GetClient(_EsConfig.url, indexName);
    }
    /// <summary>
    /// 根据url获取ElasticClient
    /// </summary>
    /// <param name="url"></param>
    /// <param name="defaultIndex"></param>
    /// <returns></returns>
    private ElasticClient GetClient(string url, string defaultIndex = "")
    {
        if (string.IsNullOrWhiteSpace(url))
        {
            throw new Exception("urls can not be null");
        }
        var uri = new Uri(url);
        var connectionSetting = new ConnectionSettings(uri);
        if (!string.IsNullOrWhiteSpace(url))
        {
            connectionSetting.DefaultIndex(defaultIndex);
        }
        connectionSetting.BasicAuthentication(_EsConfig.username, _EsConfig.password); //设置账号密码
        return new ElasticClient(connectionSetting);
    }
    /// <summary>
    /// 根据urls获取ElasticClient
    /// </summary>
    /// <param name="urls"></param>
    /// <param name="defaultIndex"></param>
    /// <returns></returns>
    private ElasticClient GetClient(string[] urls, string defaultIndex = "")
    {
        if (urls == null || urls.Length < 1)
        {
            throw new Exception("urls can not be null");
        }
        var uris = urls.Select(p => new Uri(p)).ToArray();
        var connectionPool = new SniffingConnectionPool(uris);
        var connectionSetting = new ConnectionSettings(connectionPool);
        if (!string.IsNullOrWhiteSpace(defaultIndex))
        {
            connectionSetting.DefaultIndex(defaultIndex);
        }
        return new ElasticClient(connectionSetting);
    }
}

既然是依赖注入别忘了在Startup.cs中对其进行注入。

services.Configure<EsConfig>(Configuration.GetSection("EsConfig"));

操作数据库

平时在我们操作数据库之前,我们通常会有一个“建库”、“建表”等操作,在Es中我们可以理解为创建索引基础入门 | Elasticsearch: 权威指南 | Elastic。

由于Es数据库目前还没有很好的IDE去管理它,我们通常使用代码来实现表的创建,所以先新建一个Es的拓展类来创建表ElasticClientExtension.cs

/// <summary>
/// ElasticClient 扩展类
/// </summary>
public static class ElasticClientExtension
{
    /// <summary>
    /// 创建索引
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="elasticClient"></param>
    /// <param name="indexName"></param>
    /// <param name="numberOfShards"></param>
    /// <param name="numberOfReplicas"></param>
    /// <returns></returns>
    public static bool CreateIndex<T>(this ElasticClient elasticClient, string indexName = ""int numberOfShards = 10int numberOfReplicas = 1where T : class
    {

        if (string.IsNullOrWhiteSpace(indexName))
        {
            indexName = typeof(T).Name;
        }

        if (elasticClient.Indices.Exists(indexName).Exists)
        {
            return false;
        }
        else
        {
            var indexState = new IndexState()
            {
                Settings = new IndexSettings()
                {
                    NumberOfReplicas = numberOfReplicas,
                    NumberOfShards = numberOfShards,
                },
            };
            var response = elasticClient.Indices.Create(indexName, p => p.InitializeUsing(indexState).Map<T>(p => p.AutoMap()));
            return response.Acknowledged;
        }
    }
}

然后就是需要创建我们针对索引的方法了,我使用的是一个索引新建一个方法,新建一个ElaticSearchBase.cs,在这里我们假设要创建一个叫XXX的索引,首先我们要定义好一个叫XXX的类,我这里新建了一个主键和一个xml字段,用来存储xml的数据。然后我在ElaticSearchBase.cs新建一个专属于连接XXX索引的客户端Client_XXX,如果数据库中存在xxx则直接连接,如果不存在则新建后连接。

public class XXX
{
    public int xid { getset; }
    [Text(Name = "xml")]
    public string xml { getset; }
}
public class ElaticSearchBase
{

    private IElasticsearchClient _client;
    public ElaticSearchBase(IElasticsearchClient client)
    {
        _client = client;
    }
    /// <summary>
    /// XXX文档索引
    /// </summary>
    public ElasticClient Client_XXX => GetXXX();

    private ElasticClient GetXXX()
    {
  //如果数据库中存在xxx则直接连接,如果不存在则新建后连接
        var client = _client.GetClient("XXX");
        if (!client.Indices.Exists("XXX").Exists)
        {
            client.CreateIndex<XXX>("XXX");
        }
        return client;
    }
}

接下来我们到了实操部分:

新增

private ElaticSearchBase _es = new ElaticSearchBase(_client);
//实例化对象
var xxx1 = new XXX(){tempid = 1,xml = "xmlstring"};
//存储xxx1
var res =_es.Client_XXX.IndexDocument(xxx1);
//获得Es主键
var esid = res.Id;

查询

var res = _es.Client_XXX.Get<XXX>(esid);

删除

var res = _es.Client_XXX.Delete<XXX>(esid)

修改

//实例化对象
var xxx2 = new XXX(){tempid = 2,xml = "xmlstring2"};
var upRes= _es.Client_XXX.Update<XXX, object>(ex.xmlid, upt => upt.Doc(xxx2));

还有更多的查询操作,可以查看官网内容:结构化搜索 | Elasticsearch: 权威指南 | Elastic

转自:野菊花

链接:cnblogs.com/Jackyye/p/15842333.html

- EOF -

推荐阅读  点击标题可跳转
ASP.NET Core WebAPI 实现短链接服务 .NET Core 程序集复用技术:类型转移.NET 6 揭开 ConfigurationManager 的面纱

看完本文有收获?请转发分享给更多人

推荐关注「DotNet」,提升.Net技能 

点赞和在看就是最大的支持❤️

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存