关闭

Elasticsearch.Net使用(一)【入门篇】

标签: elasticsearchc#.NET全文搜索引擎分布式
5470人阅读 评论(1) 收藏 举报
分类:

首先去官网下载Elasticsearch 2.3.4安装包,解压后,在cmd命令行进入安装目录,再进入 bin目录,运行elasticsearch.bat命令

elasticsearch插件elasticsearch-head安装:
bin目录下执行命令plugin -install mobz/elasticsearch-head

然后开始.net编程,构建控制台应用程序

Program.cs代码如下:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("*Program 开始运行 : "  + DateTime.Now);
            var business = new Business();

            var swRead = new Stopwatch();
            //swRead.Start();
            //business.AddToDb();//sqlserver数据库增加数据
            //swRead.Stop();
            //Console.WriteLine("DB 写入时间  : " + swRead.ElapsedMilliseconds);

            //swRead.Reset();
            //swRead.Start();
            //business.AddToElasticIndex();
            //swRead.Stop();
            //Console.WriteLine("ES 写入时间  : " + swRead.ElapsedMilliseconds);
            
            var sw = new Stopwatch();
            sw.Start();
            var personsFromDB = business.GetFromDB();
            sw.Stop();
            Console.WriteLine("DB 读时间  : " + sw.ElapsedMilliseconds);
            
            sw.Reset();
            sw.Start();
            var personsFromEs = business.GetFromES();
            sw.Stop();
            Console.WriteLine("ES 读时间  : " + sw.ElapsedMilliseconds);

            Console.ReadLine();
        }
    }
BLL层的Business.cs类:

public class Business
    {
        private List<PersonDetail> _personList = new List<PersonDetail>();
        
        //SQLSERVER数据库
        PersonDbProvider dbProvider = new PersonDbProvider();

        //ElasticSearch
        ESProvider esProvider = new ESProvider();

        public void AddToDb()
        {
            _personList = Util.Get10000PersonDetails();//辅助类,生成10000条数据

            foreach (var personDetail in _personList)
            {
                dbProvider.AddPerson(personDetail);
            }
        }

        public void AddToElasticIndex()
        {
            _personList = Util.Get10000PersonDetailsWithID();
            foreach (var personDetail in _personList)
            {
                esProvider.Index(personDetail);
            }
        }

        public List<PersonDetail> GetFromDB()
        {
            return dbProvider.GetAllPersonDetails();
        }

        public List<PersonDetail> GetFromES()
        {
            return esProvider.GetAll();
        }

    }
PersonDbProvider.cs和ElasticSearchProvider.cs以及Util.cs,Setting.cs类:

 public class PersonDbProvider
    {
        public bool AddPerson(PersonDetail personDetail)
        {
            try
            {   //数据库上下文
                using (var db = new PersonContext())
                {
                    db.PersonDetails.Add(personDetail);
                    db.SaveChanges();
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public List<PersonDetail> GetAllPersonDetails()
        {
            try
            {
                using (var db = new PersonContext())
                {
                    return db.PersonDetails.ToList();
                }
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
 public class ESProvider
    {
        public static ElasticClient client = new ElasticClient(Setting.ConnectionSettings);

        public bool Index(PersonDetail person)
        {
            var client = new ElasticClient(Setting.ConnectionSettings);
            try
            {
                //添加数据 
                //在调用下面的index方法的时候,如果没有指定使用哪个index,ElasticSearch会直接使用我们在setting中的defaultIndex,如果没有,则会自动创建
                var index = client.Index(person);
                return index.Created;
            }
            catch (Exception ex)
            {
                Console.WriteLine(" Excepton Message : " + ex.Message);
            }
            return false;
        }


        public List<PersonDetail> GetAll()
        {
            var searchResults = client.Search<PersonDetail>(s => s
                .From(0)
                .Size(10000)
                );
            return searchResults.Documents.ToList();
        }

        public List<PersonDetail> GetEntities(string keyword)
        {
            var client = new ElasticClient(Setting.ConnectionSettings);

            #region 全文搜索

            keyword = String.Format("*{0}*", keyword);
            //默认的Operator是Or,当keyword是类似于"One Two"之类的中间有空格的时候,会被当成两个关键词搜索,然后搜索结果进行or运算
            //所以我们需要根据需求来调整Operator
            var searchResults = client.Search<PersonDetail>(s => s
                .Index("elastic-search-app")
                .Query(q => q.QueryString(qs => qs.Query(keyword).DefaultOperator(Operator.And)))
                );

            //--------------------------------------------------------------------------------------
            //另外由于ES是分词搜索,所以当我们要用"One"来搜索完整的单词"JustOne"的时候,就必须在"One"外面添加**,类似于SQL里面的%keyword%,但是这样的做法会导致在用完整的单词来搜索的时候搜索不到结果,所以我们需要使用下面的方式

            //wholeKeyword = keyword;
            //keyword = String.Format("*{0}*", keyword);
            //QueryContainer query = new QueryStringQuery() { Query = keyword, DefaultOperator = Operator.And };
            //if (!String.IsNullOrEmpty(wholeKeyword))
            //{
            //    QueryContainer wholeWordQuery = new QueryStringQuery() { Query = wholeKeyword };
            //    query = query || wholeWordQuery;
            //}
            //var searchResults = client.Search<Person>(s => s
            //    .Index("zhixiao-application")
            //    .Query(query)
            //);

            #endregion

            #region 指定属性搜索

            //使用term Query
            //Term是一个被索引的精确值,也就是说Foo, foo, FOO是不相等的,因此
            //在使用term query的时候要注意,term query在搜索的Field已经被索引的时候,是不支持大写的。
            // QueryContainer query2 = new TermQuery { Field = item.Key, Value = item.Value.ToLower() };
            //--------------------------------------------------------------------------------------
            //var searchResults = client.Search<PersonDetail>(s => s
            //    .Index("elastic-search-app")
            //    .Query(q => q.Term(t => t.OnField(f => f.LastName == "keyword")))
            //);
            //效果同上
            //QueryContainer termQuery = new TermQuery { Field = "lastname", Value = "keyword" };
            //var searchResults = client.Search<PersonDetail>(s => s
            //    .Index("elastic-search-app")
            //    .Query(termQuery)
            //);
            //--------------------------------------------------------------------------------------
            //使用 Query String query
            //QueryString query一般用于全文搜索,但是也可以用于单个属性的搜索(设置DefaultField属性),queryString query可以不区分大小写。QueryString还有一个好处就是我们可以搜索一个term中的一部分,
            //例如lastname为"t Boterhuis 1",那么我们可以用"terhuis"搜索到这个数据(虽然需要在外面包上**),在term query里面就做不到,因为ES把每一个属性的值都分析成一个个单独的term,提高了搜索的效率。 
            //keyword = "t Boterhuis 2";
            //QueryContainer wholeWordQuery = new QueryStringQuery() { Query = keyword, DefaultOperator = Operator.And };
            //var searchResults = client.Search<PersonDetail>(s => s
            //    .Index("elastic-search-app")
            //    .Query(wholeWordQuery)
            //);

            #endregion

            return searchResults.Documents.ToList();
        }

        public List<PersonDetail> Sort(string keyword)
        {
            // 首先我们把原先的索引先删除了
            var response =
                client.DeleteIndex(
                    new DeleteIndexRequest(new IndexNameMarker()
                    {
                        Name = "elastic-search-app",
                        Type = typeof(PersonDetail)
                    }));

            //然后重新创建索引
            var indexResult = client.CreateIndex("PD-application");
            var response1 = client.Map<PersonDetail>(m => m.MapFromAttributes());
            IEnumerable<PersonDetail> persons = new List<PersonDetail>
            {
                new PersonDetail()
                {
                    Id = 4,
                    FirstName = "Boterhuis-040",
                    LastName = "Gusto-040",
                },
                new PersonDetail()
                {
                    Id = 5,
                    FirstName = "sales@historichousehotels.com",
                    LastName = "t Boterhuis 1",
                },
                new PersonDetail()
                {
                    Id = 6,
                    FirstName = "Aberdeen #110",
                    LastName = "sales@historichousehotels.com",
                },
                new PersonDetail()
                {
                    Id = 7,
                    FirstName = "Aberdeen #110",
                    LastName = "t Boterhuis 2",
                },
            };
            foreach (var person in persons)
            {
                client.Index(person);
            }
            var searchResults = client.Search<PersonDetail>(s => s
                .Index("PD-application")
                .Sort(sort => sort.OnField(f => f.Id).Order(SortOrder.Ascending))

            );
            return searchResults.Documents.ToList();
        }
    }
 public static class Util
    {

        //生成10000条sqlserver测试数据
        public static List<PersonDetail> Get10000PersonDetails()
        {
            var personDetailsList = new List<PersonDetail>();
            
            for (int i = 0; i < 10000; i++)
            {
                personDetailsList.Add(new PersonDetail()
                {
                    FirstName = "FN" + new Random().Next(int.MaxValue),
                    LastName = "LN"  + new Random().Next(int.MaxValue)
                });
            }
            return personDetailsList;
        }

        //生成10000条ElasticSearch测试数据
        public static List<PersonDetail> Get10000PersonDetailsWithID()
        {
            var personDetailsList = new List<PersonDetail>();
            
            for (int i = 0; i < 10000; i++)
            {
                personDetailsList.Add(new PersonDetail()
                {
                    Id = i * new Random().Next(99),
                    FirstName = "FN" + new Random().Next(int.MaxValue),
                    LastName = "LN" + new Random().Next(int.MaxValue)
                });
            }
            return personDetailsList;
        }

    }
 public static class Setting
    {
        public static Uri Node
        {
            get
            {
                return new Uri("http://localhost:9200");
            }
        }
        //连接配置
        public static ConnectionSettings ConnectionSettings
        {
            get
            {
                return new ConnectionSettings(Node, defaultIndex: "es-index-app");
            }
        }

    }
Model层代码:

  public partial class PersonDetail
    {
        public long Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

 public partial class PersonContext : DbContext
    {
        static PersonContext()
        {
            Database.SetInitializer<PersonContext>(null);
        }

        public PersonContext()
            : base("Name=PersonContext")
        {
        }

        public DbSet<PersonDetail> PersonDetails { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //在重写OnModelCreating方法中则可以直接调用映射类,从而减少了OnModelCreating方法的复杂度,同时也增强了代码维护的可读性
            modelBuilder.Configurations.Add(new PersonDetailMap());  //属性映射约定
        }
    }
 //Fluent API配置Configuration映射类
    public class PersonDetailMap : EntityTypeConfiguration<PersonDetail>
    {
        public PersonDetailMap()
        {
            // 主键
            this.HasKey(t => new { t.Id, t.FirstName, t.LastName });

            // 属性
            this.Property(t => t.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            this.Property(t => t.FirstName)
                .IsRequired();

            this.Property(t => t.LastName)
                .IsRequired();

            // 表 & 列 映射
            this.ToTable("PersonDetails");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.FirstName).HasColumnName("FirstName");
            this.Property(t => t.LastName).HasColumnName("LastName");
        }
    }
sqlserver脚本:

USE [Person]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[PersonDetails](
	[Id] [bigint] IDENTITY(1,1) NOT NULL,
	[FirstName] [nvarchar](max) NOT NULL,
	[LastName] [nvarchar](max) NOT NULL
) ON [PRIMARY]

GO
结果图:










0
0
查看评论

利用NEST2.0 在C#中操作Elasticsearch

本文从两个方面简单描述下NEST的用法: 索引数据 搜索数据 注意我索引数据和搜索数据是两个不同的例子。没有衔接关系 NOTE :NEST操作es,存储数据的类型应该是要已知的 准备工作:需要在visual studio 用NuGet 搜索 NEST,下载NEST 2.3即可一、索引数据:下段代...
  • yangwenbo214
  • yangwenbo214
  • 2017-03-15 15:16
  • 1520

ElasticSearch 搜索引擎,使用C# 进行查询

使用驱动: Nest(ElasticSearch 官方的C#驱动) 请注意,本人的实现思路是,在对象(对应ES的类型)上面进行打标,用来判断数据是否存在,插入ES,删除ES等操作 调用如下: 插入: ESProvider es = new ESProvider(); es.In...
  • sun491922556
  • sun491922556
  • 2018-01-09 14:33
  • 65

ElasticSearch.net第五步-c#操作ElasticSearch详解

前面我们讲解了关于ElasticSearch的安装配置,以及CRUD 本章我将讲解怎么使用c#操作ElasticSearch。 首先你需要一定的技术储备,比如:asp.net webapi,mvc,jsonp,knockout。这些知识在这里不再讲解,请自行Google。 项目DE...
  • simdrv
  • simdrv
  • 2017-11-19 07:55
  • 228

NEST.net Client For Elasticsearch简单应用

NEST.net Client For elasticsearch简单应用
  • huwei2003
  • huwei2003
  • 2014-11-10 15:02
  • 10003

Elasticsearch.Net使用(二)【MVC4 图书管理系统】

首先项目结构图: Model层的相关代码如下: Book.cs代码如下: public class Book { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] ...
  • WuLex
  • WuLex
  • 2016-08-07 19:19
  • 4216

ElasticSearch.net NEST批量创建修改删除索引完整示例

本示例采用Elasticsearch+Nest 网上查了很多资料,发现用C#调用Elasticsearch搜索引擎的功能代码很分散,功能不完整,多半是非常简单的操作,没有成型的应用示例。比如新增或修改索引,都是发起一个request新增或修改一条数据,当一次性修改几千条数据时,发起的requst请求...
  • qq_18145031
  • qq_18145031
  • 2016-12-02 19:57
  • 3022

ElasticSearch.net结构化查询

ES_PUB_Stock这个类型定义先看之前写的文章, 以下直接列出查询方法。 public PUB_StockSearchResult Search(PUB_StockSearch param)         {      ...
  • qq_18145031
  • qq_18145031
  • 2017-04-21 16:39
  • 654

Elasticsearch(二)【Elasticsearch.Net基本使用】

低级客户端ElasticLowLevelClient是一个低级的,无依赖的客户端,对如何构建和表示您的请求和响应没有意见。它可以从Visual Studio中的包管理器控制台安装使用Install-Package Elasticsearch.Net连接要连接到本地运行在http://localhos...
  • WuLex
  • WuLex
  • 2017-03-22 14:09
  • 2744

Elasticsearch 数据搜索篇·【入门级干货】

Elasticsearch 数据搜索篇·【入门级干货】 ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API。本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用。虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的特性。 ...
  • sxf_123456
  • sxf_123456
  • 2017-07-31 15:38
  • 232

.NET 分布式 搜索 elasticsearch.net NEST

我们公司(电商)目前使用 elasticsearch。对于一个3亿数据量索引查询速度都是在毫秒级别,不过实现都是基于JAVA的client. 本人因为是.NET出身,虽然现在做JAVA。但是对.NET情有独钟。所以闲暇时间研究了下 elasticsearch的.NET 的CLIENT的NEST.希望...
  • kingson88
  • kingson88
  • 2016-04-26 18:07
  • 2567
    个人资料
    • 访问:1297286次
    • 积分:18616
    • 等级:
    • 排名:第593名
    • 原创:312篇
    • 转载:932篇
    • 译文:123篇
    • 评论:297条
    博客专栏
    文章分类
    打赏
    如果你觉得我的文章对您有用,请随意打赏。 微信 支付宝