C#使用ES
2017-01-12 07:44
429 查看
C#如何使用ES
Elasticsearch简介但是,Lucene只是一个库。想要发挥其强大的作用,你需使用C#将其集成到你的应用中。Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。
Elasticsearch是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTfulAPI让全文搜索变得简单并隐藏Lucene的复杂性。
不过,Elasticsearch不仅仅是Lucene和全文搜索引擎,它还提供:
分布式的实时文件存储,每个字段都被索引并可被搜索
实时分析的分布式搜索引擎
可以扩展到上百台服务器,处理PB级结构化或非结构化数据
而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的RESTfulAPI、各种语言的客户端甚至命令行与之交互。上手Elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。Elasticsearch在Apache2license下许可使用,可以免费下载、使用和修改。
随着知识的积累,你可以根据不同的问题领域定制Elasticsearch的高级特性,这一切都是可配置的,并且配置非常灵活。
以上内容来自
关于ES详细概念见:
使用C#操作ES
NEST是一个高层的客户端,可以映射所有请求和响应对象,拥有一个强类型查询DSL(领域特定语言),并且可以使用.net的特性比如协变、AutoMappingOfPOCOs,NEST内部使用的依然是Elasticsearch.Net客户端。elasticsearch.net(NEST)客户端提供了强类型查询DSL,方便用户使用,
一、如何安装NEST
打开VS的工具菜单,通过NuGet包管理器控制台,输入以下命令安装NESTInstall-PackageNEST
安装后引用了以下三个DLL
Elasticsearch.Net.dll(2.4.4) Nest.dll(2.4.4) Newtonsoft.Json.dll(9.0版本)
二、链接elasticsearch
你可以通过单个节点或者指定多个节点使用连接池链接到Elasticsearch集群,使用连接池要比单个节点链接到Elasticsearch更有优势,比如支持负载均衡、故障转移等。通过单点链接:
1varnode=newUri("http://myserver:9200"); 2varsettings=newConnectionSettings(node); 3varclient=newElasticClient(settings);
通过连接池链接:
1varnodes=newUri[] 2{ 3newUri("http://myserver1:9200"), 4newUri("http://myserver2:9200"), 5newUri("http://myserver3:9200") 6}; 7 8varpool=newStaticConnectionPool(nodes); 9varsettings=newConnectionSettings(pool); 10varclient=newElasticClient(settings);
NESTIndex
为了知道请求需要操作哪个索引,ElasticsearchAPI期望收到一个或多个索引名称作为请求的一部分。一、指定索引
1、可以通过ConnectionSettings使用.DefaultIndex(),来指定默认索引。当一个请求里没有指定具体索引时,NEST将请求默认索引。1varsettings=newConnectionSettings() 2.DefaultIndex("defaultindex");
2、可以通过ConnectionSettings使用.MapDefaultTypeIndices(),来指定被映射为CLR类型的索引。
1varsettings=newConnectionSettings() 2.MapDefaultTypeIndices(m=>m 3.Add(typeof(Project),"projects") 4);
注意:通过.MapDefaultTypeIndices()指定索引的优先级要高于通过.DefaultIndex()指定索引,并且更适合简单对象(POCO)
3、另外还可以显示的为请求指定索引名称,例如:
1varresponse=client.Index(student,s=>s.Index("db_test")); 2varresult=client.Search<Student>(s=>s.Index("db_test")); 3varresult=client.Delete<Student>(null,s=>s.Index("db_test")); 4……
注意:当现实的为请求指定索引名称时,这个优先级是最高的,高于以上两种方式指定的索引。
4、一些ElasticsearchAPI(比如query)可以采用一个、多个索引名称或者使用_all特殊标志发送请求,请求NEST上的多个或者所有节点
1//请求单一节点 2varsingleString=Nest.Indices.Index("db_studnet"); 3varsingleTyped=Nest.Indices.Index<Student>(); 4 5ISearchRequestsingleStringRequest=newSearchDescriptor<Student>().Index(singleString); 6ISearchRequestsingleTypedRequest=newSearchDescriptor<Student>().Index(singleTyped); 7 8//请求多个节点 9varmanyStrings=Nest.Indices.Index("db_studnet","db_other_student"); 10varmanyTypes=Nest.Indices.Index<Student>().And<OtherStudent>(); 11 12ISearchRequestmanyStringRequest=newSearchDescriptor<Student>().Index(manyStrings); 13ISearchRequestmanyTypedRequest=newSearchDescriptor<Student>().Index(manyTypes); 14 15//请求所有节点 16varindicesAll=Nest.Indices.All; 17varallIndices=Nest.Indices.AllIndices; 18 19ISearchRequestindicesAllRequest=newSearchDescriptor<Student>().Index(indicesAll); 20ISearchRequestallIndicesRequest=newSearchDescriptor<Student>().Index(allIndices);
二、创建索引
ElasticsearchAPI允许你创建索引的同时对索引进行配置,例如:1vardescriptor=newCreateIndexDescriptor("db_student") 2.Settings(s=>s.NumberOfShards(5).NumberOfReplicas(1)); 3 4client.CreateIndex(descriptor);
这里指定了该索引的分片数为5、副本数为1。
三、删除索引
ElasticsearchAPI允许你删除索引,例如:1vardescriptor=newDeleteIndexDescriptor("db_student").Index("db_student"); 2 3client.DeleteIndex(descriptor)
这里制定了要删除的索引名称“db_student”,以下为更多删除用例:
1//删除指定索引所在节点下的所有索引 2vardescriptor=newDeleteIndexDescriptor("db_student").AllIndices();
NESTMapping
NEST提供了多种映射方法,这里介绍下通过Attribute自定义映射。一、简单实现
1、定义业务需要的POCO,并指定需要的Attribute1[ElasticsearchType(Name="student")] 2publicclassStudent 3{ 4[Nest.String(Index=FieldIndexOption.NotAnalyzed)] 5publicstringId{get;set;} 6 7[Nest.String(Analyzer="standard")] 8publicstringName{get;set;} 9 10[Nest.String(Analyzer="standard")] 11publicstringDescription{get;set;} 12 13publicDateTimeDateTime{get;set;} 14}
2、接着我们通过.AutoMap()来实现映射
1vardescriptor=newCreateIndexDescriptor("db_student") 2.Settings(s=>s.NumberOfShards(5).NumberOfReplicas(1)) 3.Mappings(ms=>ms 4.Map<Student>(m=>m.AutoMap()) 5); 6 7client.CreateIndex(descriptor);
注意:通过.Properties()可以重写通过Attribute定义的映射
二、Attribute介绍
1、StringAttribute属性名 | 值类型 | 描述 |
---|---|---|
Analyzer | string | 分析器名称,值包含standard、simple、whitespace、stop、keyward、pattern、language、snowball、custom等,查看分析器更多信息请点击 |
Boost | double | 加权值,值越大得分越高 |
NullValue | string | 插入文档时,如果数据为NULL时的默认值 |
Index | FieldIndexOption | 是否使用分析器,默认使用FieldIndexOption.Analyzed,禁止使用分析器FieldIndexOption.NotAnalyzed |
属性名 | 值类型 | 描述 |
---|---|---|
type | NumberType | 构造函数参数,指定当前属性的类型,NumberType.Default、Float、Double、Integer、Long、Short、Byte |
Boost | double | 加权值,值越大得分越高 |
NullValue | double | 插入文档时,如果数据为NULL时的默认值 |
属性名 | 值类型 | 描述 |
---|---|---|
Boost | double | 加权值,值越大得分越高 |
NullValue | double | 插入文档时,如果数据为NULL时的默认值 |
属性名 | 值类型 | 描述 |
---|---|---|
Boost | double | 加权值,值越大得分越高 |
NullValue | string | 插入文档时,如果数据为NULL时的默认值 |
Format | string |
属性名 | 值类型 | 描述 |
---|---|---|
type | string/Type | 构造函数参数,指定当前属性的类型T |
Dynamic | DynamicMapping |
NESTSearch
NEST提供了支持Lambda链式queryDLS(领域特定语言)方式,以下是简单实现及各个query的简述。一、简单实现
1、定义SearchDescriptor,方便项目中复杂业务的实现1varquery=newNest.SearchDescriptor<Models.ESObject>(); 2 3varresult=client.Search<Student>(x=>query)
2、检索title和content中包含key,并且作者不等于“俏佳人”的文档
1query.Query(q=> 2q.Bool(b=> 3b.Must(m=> 4m.MultiMatch(t=>t.Fields(f=>f.Field(obj=>obj.Title).Field(obj=>obj.Content)).Query(key)) 5) 6.MustNot(m=> 7m.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、过滤作者等于“历史小河”或者等于“友谊的小船”的文档,匹配多个作者中间用空格隔开
1query.PostFilter(x=>x.QueryString(t=>t.Fields(f=>f.Field(obj=>obj.Author)).Query("wenliyswenli")));
5、过滤数量在1~100之间的文档
1query.PostFilter(x=>x.Range(t=>t.Field(obj=>obj.Number).GreaterThanOrEquals(1).LessThanOrEquals(100)));
6、排序,按照得分倒叙排列
1query.Sort(x=>x.Field("_score",Nest.SortOrder.Descending));
7、定义高亮样式及字段
1query.Highlight(h=>h
2.PreTags("<b>")
3.PostTags("</b>")
4.Fields(
5f=>f.Field(obj=>obj.Title),
6f=>f.Field(obj=>obj.Content),
7f=>f.Field("_all")
8)
9);
8、拼装查询内容,整理数据,方便前段调用
1varlist=result.Hits.Select(c=>newModels.ESObject()
2{
3Id=c.Source.Id,
4Title=c.Highlights==null?c.Source.Title:c.Highlights.Keys.Contains("title")?string.Join("",c.Highlights["title"].Highlights):c.Source.Title,//高亮显示的内容,一条记录中出现了几次
5Content=c.Highlights==null?c.Source.Content:c.Highlights.Keys.Contains("content")?string.Join("",c.Highlights["content"].Highlights):c.Source.Content,//高亮显示的内容,一条记录中出现了几次
6Author=c.Source.Author,
7Number=c.Source.Number,
8IsDisplay=c.Source.IsDisplay,
9Tags=c.Source.Tags,
10Comments=c.Source.Comments,
11DateTime=c.Source.DateTime,
12})
二、queryDSL介绍
待整理……elasticsearch.netDocument
文档操作包含添加/更新文档、局部更新文档、删除文档及对应的批量操作文档方法。一、添加/更新文档及批量操作
添加/更新单一文档1Client.Index(student);
批量添加/更新文档
1varlist=newList<Student>();
2
3client.IndexMany<Student>(list);
二、局部更新单一文档及批量操作
局部更新单一文档1client.Update<Student,object>("002",upt=>upt.Doc(new{Name="wenli"}));
局部更新批量文档
varids=newList<string>(){"002"};
varbulkQuest=newBulkRequest(){Operations=newList<IBulkOperation>()};
foreach(varvinids)
{
varoperation=newBulkUpdateOperation<Student,object>(v);
operation.Doc=new{Name="wenli"};
bulkQuest.Operations.Add(operation);
}
varresult=client.Bulk(bulkQuest);
三、删除文档及批量操作
删除单一文档1client.Delete<Student>("001");
批量删除文档
1varids=newList<string>(){"001","002"};
2
3varbulkQuest=newBulkRequest(){Operations=newList<IBulkOperation>()};
4
5foreach(varvinids)
6{
7bulkQuest.Operations.Add(newBulkDeleteOperation<Student>(v));
8}
9
10varresult=client.Bulk(bulkQuest);
转载请标明本文来源:
更多内容欢迎我的的github:
如果发现本文有什么问题和任何建议,也随时欢迎交流~
相关文章推荐
- C# 关于委托的小例子
- C#获取本机局域网ip和公网ip
- C# delegate event
- c#之集学习笔记
- C#EXCEL转PDF
- C#读取word文档中的内容
- C# Timer
- C#值类型和引用类型与Equals方法
- C# 中DateTime的各种使用
- c#系统硬件信息
- c#获取本机IP
- C#IDisposable 接口&资源释放
- C#析构函数
- C# 托管资源 与 非托管资源
- C# 进制转换(二进制、八进制、十进制、十六进制互转)
- PowerDesigner16.5物理数据表生成C#实体类Model
- C# 关于Zookeeper的分步式锁
- c#面向对象
- C#中const与readonly的区别之浅见
- C#判断光标是否属于输入状态