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运算//所以我们需要根据需求来调整Operatorvar 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] GOSET ANSI_NULLS ON GOSET QUOTED_IDENTIFIER ON GOCREATE TABLE [dbo].[PersonDetails]([Id] [bigint] IDENTITY(1,1) NOT NULL,[FirstName] [nvarchar](max) NOT NULL,[LastName] [nvarchar](max) NOT NULL ) ON [PRIMARY]GO结果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。