>  기사  >  백엔드 개발  >  Elasticsearch.Net 튜토리얼 시작하기(1)

Elasticsearch.Net 튜토리얼 시작하기(1)

高洛峰
高洛峰원래의
2016-12-20 13:58:352714검색

본 글의 예시는 참고용으로 Elasticsearch.Net 사용법에 대한 튜토리얼을 공유하고 있습니다. 구체적인 내용은 다음과 같습니다

먼저 공식 홈페이지에 접속하여 Elasticsearch 2.3.4 설치 패키지를 다운로드 받으세요. 압축을 풀고 cmd 명령줄에 설치 디렉터리를 입력한 다음 bin 디렉터리를 입력하고 elasticsearch.bat 명령을 실행하세요.

강좌 추천 →: "Elasticsearch 전체 텍스트 검색 실습"(실습 영상)

강좌에서 《 수천만 개의 데이터 동시성 솔루션(이론적 + 실제적)》

elasticsearch 플러그인 elasticsearch-head 설치:

명령 플러그인 실행 - bin 디렉토리 /elasticsearch-head에 mobz를 설치하세요

그런 다음 .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"); 
   } 
  } 
  
 }

모델 레이어 코드:

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

결과 그래프:

Elasticsearch.Net 튜토리얼 시작하기(1)

이상 이 글의 내용이 모두의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 PHP 중국어 웹사이트를 지지해 주시길 바랍니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.