The project needs to add Elasticsearch.Net and Nest

Address of relevant documents

Elasticsearch document: www.elastic.co/guide/en/el…

Elasticsearch.Net and Nest the official document: www.elastic.co/guide/en/el…

Encapsulate the ElasticClient provider

1) Create the ElasticSearch configuration class

public class EsConfig : IOptions<EsConfig>
    {
        public List<string> Urls { get; set; }

        public EsConfig Value => this;
    }
Copy the code

2) Create the ElasticSearch provider interface and classes

/// <summary>
    ///ElasticClient provider interface
    /// </summary>
    public interface IEsClientProvider
    {
        /// <summary>
        ///Get ElasticClient
        /// </summary>
        /// <returns></returns>
        ElasticClient GetClient();
        /// <summary>
        ///Obtain ElasticClient by specifying index
        /// </summary>
        /// <param name="indexName"></param>
        /// <returns></returns>
        ElasticClient GetClient(string indexName);
    }



    /// <summary>
    ///ElasticClient provider
    /// </summary>
    public class EsClientProvider : IEsClientProvider
    {
        private readonly IOptions<EsConfig> _EsConfig;
        public EsClientProvider(IOptions<EsConfig> esConfig)
        {
            _EsConfig = esConfig;
        }
        /// <summary>
        ///To obtain an elastic client
        /// </summary>
        /// <returns></returns>
        public ElasticClient GetClient()
        {
            if (_EsConfig == null || _EsConfig.Value == null || _EsConfig.Value.Urls == null || _EsConfig.Value.Urls.Count < 1)
            {
                throw new Exception("urls can not be null");
            }
            return GetClient(_EsConfig.Value.Urls.ToArray(), "");
        }
        /// <summary>
        ///Obtain ElasticClient by specifying index
        /// </summary>
        /// <param name="indexName"></param>
        /// <returns></returns>
        public ElasticClient GetClient(string indexName)
        {
            if (_EsConfig == null || _EsConfig.Value == null || _EsConfig.Value.Urls == null || _EsConfig.Value.Urls.Count < 1)
            {
                throw new Exception("urls can not be null");
            }
            return GetClient(_EsConfig.Value.Urls.ToArray(), indexName);
        }


        /// <summary>
        ///Obtain ElasticClient from the URL
        /// </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("Es address cannot be empty");
            }
            var uri = new Uri(url);
            var connectionSetting = new ConnectionSettings(uri);
            if (!string.IsNullOrWhiteSpace(url))
            {
                connectionSetting.DefaultIndex(defaultIndex);
            }
            return new ElasticClient(connectionSetting);
        }
        /// <summary>
        ///Get ElasticClient from urls
        /// </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 newElasticClient(connectionSetting); }}Copy the code

——— User password authentication (note) can be configured in EsConfig ———

/// <summary>
        ///Get ElasticClient from urls
        /// </summary>
        /// <param name="urls"></param>
        /// <param name="defaultIndex"></param>
        /// <returns></returns>
        public 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);
            }
            //connectionSetting.BasicAuthentication("", ""); // Set the account password
            return new ElasticClient(connectionSetting);
        }
Copy the code

2, encapsulation operation ElasticSearch implementation

1) Extend ElasticClient class

/// <summary>
    ///ElasticClient extension class
    /// </summary>
    public static class ElasticClientExtension
    {
        /// <summary>
        ///Create indexes
        /// </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 = 5.int numberOfReplicas = 1) where 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()));
                returnresponse.Acknowledged; }}}Copy the code

Create base class for ElasticSearch

/// <summary>
    ///Interface is limited
    /// </summary>
    public interface IBaseEsContext{}/// <summary>
    ///Es operates on base classes
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class BaseEsContext<T> : IBaseEsContext where T : class
    {
        protected IEsClientProvider _EsClientProvider;
        public abstract string IndexName { get;  }
        public BaseEsContext(IEsClientProvider provider)
        {
            _EsClientProvider = provider;
        }

        /// <summary>
        ///Batch update
        /// </summary>
        /// <param name="tList"></param>
        /// <returns></returns>
        public bool InsertMany(List<T> tList)
        {
            var client = _EsClientProvider.GetClient(IndexName);
            if(! client.Indices.Exists(IndexName).Exists) { client.CreateIndex<T>(IndexName); }var response = client.IndexMany(tList);
            //var response = client.Bulk(p=>p.Index(IndexName).IndexMany(tList));
            return response.IsValid;
        }

        /// <summary>
        ///Get the total number of
        /// </summary>
        /// <returns></returns>
        public long GetTotalCount()
        {
            var client = _EsClientProvider.GetClient(IndexName);
            var search = new SearchDescriptor<T>().MatchAll(); / / the specified query field. The Source (p = > p.I ncludes (x = > x.F ield (" Id ")));
            var response = client.Search<T>(search);
            return response.Total;
        }
        /// <summary>
        ///Delete data by Id
        /// </summary>
        /// <returns></returns>
        public bool DeleteById(string id)
        {
            var client = _EsClientProvider.GetClient(IndexName);
            var response = client.Delete<T>(id);
            returnresponse.IsValid; }}Copy the code

3) Specific operations (examples)

/// <summary>
    ///Address manipulation class
    /// </summary>
    public class AddressContext : BaseEsContext<Address>
    {
        /// <summary>
        ///The index name
        /// </summary>
        public override string IndexName => "address";
        public AddressContext(IEsClientProvider provider) : base(provider){}/// <summary>
        ///Get the address
        /// </summary>
        /// <param name="province"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<Address> GetAddresses(string province, int pageIndex, int pageSize)
        {
            var client = _EsClientProvider.GetClient(IndexName);
            var musts = new List<Func<QueryContainerDescriptor<Address>, QueryContainer>>();
            musts.Add(p => p.Term(m => m.Field(x=>x.Pronvince).Value(province)));
            var search = new SearchDescriptor<Address>();
           // search = search.Index(IndexName).Query(p => p.Bool(m => m.Must(musts))).From((pageIndex - 1) * pageSize).Take(pageSize);
            search =search.Query(p => p.Bool(m => m.Must(musts))).From((pageIndex - 1) * pageSize).Take(pageSize);
            var response = client.Search<Address>(search);
            return response.Documents.ToList();
        }
        /// <summary>
        ///Get all addresses
        /// </summary>
        /// <returns></returns>
        public List<Address> GetAllAddresses()
        {
            var client = _EsClientProvider.GetClient(IndexName);
            var searchDescriptor = new SearchDescriptor<Address>();
            // searchDescriptor = searchDescriptor.Index(IndexName).Query(p => p.MatchAll());
            searchDescriptor = searchDescriptor.Query(p => p.MatchAll());
            var response = client.Search<Address>(searchDescriptor);
            return response.Documents.ToList();
        }
        /// <summary>
        ///Delete data for the specified city
        /// </summary>
        /// <param name="city"></param>
        /// <returns></returns>
        public bool DeleteByQuery(string city)
        {
            var client = _EsClientProvider.GetClient(IndexName);
            var musts = new  List<Func<QueryContainerDescriptor<Address>, QueryContainer>>();
            musts.Add(p=>p.Term(m=>m.Field(f=>f.City).Value(city)));
            var search = new DeleteByQueryDescriptor<Address>().Index(IndexName);
            search = search.Query(p => p.Bool(m => m.Must(musts)));
            var response = client.DeleteByQuery<Address>(p=>search);
            returnresponse.IsValid; }}Copy the code

Address class

[ElasticsearchType(IdProperty = "Id")]
    public class Address{[Keyword]
        public string Id { get; set; }
        [Keyword]
        public string Country { get; set; }
        [Keyword]
        public string City { get; set; }
        [Keyword]
        public string Pronvince { get; set; }
        [Keyword]
        public string Area { get; set; }
        [Text]
        public string Address1 { get; set; }}Copy the code

Inject and use ElasticSearch in your project

1) Configuration files

1   "EsConfig": {
2     "ConnectionStrings": [ "http://127.0.0.1:9200/" ] 
3   }
Copy the code

Insert ElasticSearch

services.Configure<EsConfig>(options =>
          {
              options.Urls = Configuration.GetSection("EsConfig:ConnectionStrings").GetChildren().ToList().Select(p => p.Value).ToList();

          });


            services.AddSingleton<IEsClientProvider, EsClientProvider>();
            var types = Assembly.Load("John.DotNetCoreStudy.EsCommon").GetTypes().Where(p => ! p.IsAbstract && (p.GetInterfaces().Any(i => i ==typeof(IBaseEsContext)))).ToList();
            types.ForEach(p =>
                    services.AddTransient(p)
                );
Copy the code

3) Used in the Controller class

[Route("api/[controller]")]
    [ApiController]
    public class AddressController : ControllerBase
    {
        private AddressContext _AddressContext;
        public AddressController(AddressContext context)
        {
            _AddressContext = context;
        }
        /// <summary>
        ///Add or modify
        /// </summary>
        /// <param name="address"></param>
        [HttpPost("Add address")]
        public void AddAddress(List<Address> addressList)
        {
            if (addressList == null || addressList.Count < 1)
            {
                return;
            }
            _AddressContext.InsertMany(addressList);
        }

        /// <summary>
        ///Delete the address
        /// </summary>
        /// <param name="id"></param>
        [HttpPost("deleteAddress")]
        public void DeleteAdress(string id)
        {
            _AddressContext.DeleteById(id);
        }
        /// <summary>
        ///Get all and address
        /// </summary>
        /// <returns></returns>
        [HttpGet("getAllAddress")]
        public List<Address> GetAllAddress()
        {
            return _AddressContext.GetAllAddresses();
        }
        /// <summary>
        ///Get total addresses
        /// </summary>
        /// <returns></returns>
        [HttpGet("getAddressTotalCount")]
        public long GetAddressTotalCount()
        {
            return _AddressContext.GetTotalCount();
        }

        /// <summary>
        ///Paging fetch (to further encapsulate query criteria)
        /// </summary>
        /// <param name="province"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpPost("getAddressByProvince")]
        public List<Address> GetAddressByProvince(string province,int pageIndex,int pageSize)
        {
            return_AddressContext.GetAddresses(province,pageIndex,pageSize); }}Copy the code

4. Test (omitted)









Of course, ES also has many operations, aggregation query, different conditions of the query (range query, matching query, etc.), word segmentation, etc. Specific can go to see its official document corresponding implementation!