在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Elasticsearch简介 Elasticsearch (ES)是一个基于Apache Lucene(TM)的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。 但是,Lucene只是一个库。想要发挥其强大的作用,你需使用C#将其集成到你的应用中。Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。
而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的RESTful API、各种语言的客户端甚至命令行与之交互。上手Elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。Elasticsearch在Apache 2 license下许可使用,可以免费下载、使用和修改。 以上内容来自 [百度百科] 关于ES详细概念见:http://88250.b3log.org/full-text-search-elasticsearch#b3_solo_h3_0
使用C#操作ES NEST是一个高层的客户端,可以映射所有请求和响应对象,拥有一个强类型查询DSL(领域特定语言),并且可以使用.net的特性比如协变、Auto Mapping Of POCOs,NEST内部使用的依然是Elasticsearch.Net客户端。elasticsearch.net(NEST)客户端提供了强类型查询DSL,方便用户使用,源码下载。 一、如何安装NEST打开VS的工具菜单,通过NuGet包管理器控制台,输入以下命令安装NEST Install-Package NEST 安装后引用了以下三个DLL Elasticsearch.Net.dll(2.4.4)
Nest.dll(2.4.4)
Newtonsoft.Json.dll(9.0版本)
二、链接elasticsearch你可以通过单个节点或者指定多个节点使用连接池链接到Elasticsearch集群,使用连接池要比单个节点链接到Elasticsearch更有优势,比如支持负载均衡、故障转移等。 通过单点链接: 1 var node = new Uri("http://myserver:9200"); 2 var settings = new ConnectionSettings(node); 3 var client = new ElasticClient(settings);
通过连接池链接: 1 var nodes = new Uri[] 2 { 3 new Uri("http://myserver1:9200"), 4 new Uri("http://myserver2:9200"), 5 new Uri("http://myserver3:9200") 6 }; 7 8 var pool = new StaticConnectionPool(nodes); 9 var settings = new ConnectionSettings(pool); 10 var client = new ElasticClient(settings);
NEST Index为了知道请求需要操作哪个索引,Elasticsearch API期望收到一个或多个索引名称作为请求的一部分。 一、指定索引1、可以通过ConnectionSettings使用.DefaultIndex(),来指定默认索引。当一个请求里没有指定具体索引时,NEST将请求默认索引。 1 var settings = new ConnectionSettings() 2 .DefaultIndex("defaultindex"); 2、可以通过ConnectionSettings使用.MapDefaultTypeIndices(),来指定被映射为CLR类型的索引。 1 var settings = new ConnectionSettings() 2 .MapDefaultTypeIndices(m => m 3 .Add(typeof(Project), "projects") 4 );
注意:通过.MapDefaultTypeIndices()指定索引的优先级要高于通过.DefaultIndex()指定索引,并且更适合简单对象(POCO) 3、另外还可以显示的为请求指定索引名称,例如: 1 var response = client.Index(student, s=>s.Index("db_test")); 2 var result = client.Search<Student>(s => s.Index("db_test")); 3 var result = client.Delete<Student>(null, s => s.Index("db_test")); 4 ……
注意:当现实的为请求指定索引名称时,这个优先级是最高的,高于以上两种方式指定的索引。 4、一些Elasticsearch API(比如query)可以采用一个、多个索引名称或者使用_all特殊标志发送请求,请求NEST上的多个或者所有节点 1 //请求单一节点 2 var singleString = Nest.Indices.Index("db_studnet"); 3 var singleTyped = Nest.Indices.Index<Student>(); 4 5 ISearchRequest singleStringRequest = new SearchDescriptor<Student>().Index(singleString); 6 ISearchRequest singleTypedRequest = new SearchDescriptor<Student>().Index(singleTyped); 7 8 //请求多个节点 9 var manyStrings = Nest.Indices.Index("db_studnet", "db_other_student"); 10 var manyTypes = Nest.Indices.Index<Student>().And<OtherStudent>(); 11 12 ISearchRequest manyStringRequest = new SearchDescriptor<Student>().Index(manyStrings); 13 ISearchRequest manyTypedRequest = new SearchDescriptor<Student>().Index(manyTypes); 14 15 //请求所有节点 16 var indicesAll = Nest.Indices.All; 17 var allIndices = Nest.Indices.AllIndices; 18 19 ISearchRequest indicesAllRequest = new SearchDescriptor<Student>().Index(indicesAll); 20 ISearchRequest allIndicesRequest = new SearchDescriptor<Student>().Index(allIndices);
二、创建索引Elasticsearch API允许你创建索引的同时对索引进行配置,例如: 1 var descriptor = new CreateIndexDescriptor("db_student") 2 .Settings(s => s.NumberOfShards(5).NumberOfReplicas(1)); 3 4 client.CreateIndex(descriptor);
这里指定了该索引的分片数为5、副本数为1。 三、删除索引Elasticsearch API允许你删除索引,例如: 1 var descriptor = new DeleteIndexDescriptor("db_student").Index("db_student"); 2 3 client.DeleteIndex(descriptor)
这里制定了要删除的索引名称“db_student”,以下为更多删除用例: 1 //删除指定索引所在节点下的所有索引 2 var descriptor = new DeleteIndexDescriptor("db_student").AllIndices();
NEST MappingNEST提供了多种映射方法,这里介绍下通过Attribute自定义映射。 一、简单实现1、定义业务需要的POCO,并指定需要的Attribute 1 [ElasticsearchType(Name = "student")] 2 public class Student 3 { 4 [Nest.String(Index = FieldIndexOption.NotAnalyzed)] 5 public string Id { get; set; } 6 7 [Nest.String(Analyzer = "standard")] 8 public string Name { get; set; } 9 10 [Nest.String(Analyzer = "standard")] 11 public string Description { get; set; } 12 13 public DateTime DateTime { get; set; } 14 }
2、接着我们通过.AutoMap()来实现映射 1 var descriptor = new CreateIndexDescriptor("db_student") 2 .Settings(s => s.NumberOfShards(5).NumberOfReplicas(1)) 3 .Mappings(ms => ms 4 .Map<Student>(m => m.AutoMap()) 5 ); 6 7 client.CreateIndex(descriptor);
注意:通过.Properties()可以重写通过Attribute定义的映射 二、Attribute介绍1、StringAttribute
2、NumberAttribute
3、BooleanAttribute
4、DateAttribute
5、ObjectAttribute
NEST SearchNEST提供了支持Lambda链式query DLS(领域特定语言)方式,以下是简单实现及各个query的简述。 一、简单实现1、定义SearchDescriptor,方便项目中复杂业务的实现 1 var query = new Nest.SearchDescriptor<Models.ESObject>(); 2 3 var result = client.Search<Student>(x => query) 2、检索title和content中包含key,并且作者不等于“俏佳人”的文档 1 query.Query(q => 2 q.Bool(b => 3 b.Must(m => 4 m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content)).Query(key)) 5 ) 6 .MustNot(m => 7 m.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli")) 8 ) 9 ) 10 );
注意: 如果Elasticsearch使用默认分词,Title和Content的attribute为[Nest.String(Analyzer = "standard")] 如果Elasticsearch使用的是IK分词,Title和Content的attribute为[Nest.String(Analyzer = "ikmaxword")]或者[Nest.String(Analyzer = "ik_smart")] Author的attribute为[Nest.String(Index = FieldIndexOption.NotAnalyzed)],禁止使用分析器 3、过滤作者等于“历史小河”的文档 query.PostFilter(x => x.Term(t => t.Field(obj => obj.Author).Value("wenli"))); 4、过滤作者等于“历史小河”或者等于“友谊的小船”的文档,匹配多个作者中间用空格隔开 1 query.PostFilter(x => x.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli yswenli"))); 5、过滤数量在1~100之间的文档 1 query.PostFilter(x => x.Range(t => t.Field(obj => obj.Number).GreaterThanOrEquals(1).LessThanOrEquals(100)));
6、排序,按照得分倒叙排列 1 query.Sort(x => x.Field("_score", Nest.SortOrder.Descending));
7、定义高亮样式及字段 1 query.Highlight(h => h 2 .PreTags("<b>") 3 .PostTags("</b>") 4 .Fields( 5 f => f.Field(obj => obj.Title), 6 f => f.Field(obj => obj.Content), 7 f => f.Field("_all") 8 ) 9 );
8、拼装查询内容,整理数据,方便前段调用 1 var list = result.Hits.Select(c => new Models.ESObject() 2 { 3 Id = c.Source.Id, 4 Title = c.Highlights == null ? c.Source.Title : c.Highlights.Keys.Contains("title") ? string.Join("", c.Highlights["title"].Highlights) : c.Source.Title, //高亮显示的内容,一条记录中出现了几次 5 Content = c.Highlights == null ? c.Source.Content : c.Highlights.Keys.Contains("content") ? string.Join("", c.Highlights["content"].Highlights) : c.Source.Content, //高亮显示的内容,一条记录中出现了几次 6 Author = c.Source.Author, 7 Number = c.Source.Number, 8 IsDisplay = c.Source.IsDisplay, 9 Tags = c.Source.Tags, 10 Comments = c.Source.Comments, 11 DateTime = c.Source.DateTime, 12 })
二、query DSL介绍待整理…… elasticsearch.net Document文档操作包含添加/更新文档、局部更新文档、删除文档及对应的批量操作文档方法。 一、添加/更新文档及批量操作添加/更新单一文档 1 Client.Index(student);
批量添加/更新文档 1 var list = new List<Student>(); 2 3 client.IndexMany<Student>(list);
二、局部更新单一文档及批量操作局部更新单一文档 1 client.Update<Student, object>("002", upt => upt.Doc(new { Name = "wenli" }));
局部更新批量文档 var ids = new List<string>() { "002" }; var bulkQuest = new BulkRequest() { Operations = new List<IBulkOperation>() }; foreach (var v in ids) { var operation = new BulkUpdateOperation<Student, object>(v); operation.Doc = new { Name = "wenli" }; bulkQuest.Operations.Add(operation); } var result = client.Bulk(bulkQuest);
三、删除文档及批量操作删除单一文档 1 client.Delete<Student>("001");
批量删除文档 1 var ids = new List<string>() { "001", "002" }; 2 3 var bulkQuest = new BulkRequest() { Operations = new List<IBulkOperation>() }; 4 5 foreach (var v in ids) 6 { 7 bulkQuest.Operations.Add(new BulkDeleteOperation<Student>(v)); 8 } 9 10 var result = client.Bulk(bulkQuest);
|
请发表评论