您的位置:首页 > 编程语言 > C#

C#使用ES

2017-01-12 07:44 429 查看

C#如何使用ES

Elasticsearch简介

Elasticsearch(ES)是一个基于ApacheLucene(TM)的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。

但是,Lucene只是一个库。想要发挥其强大的作用,你需使用C#将其集成到你的应用中。Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。
Elasticsearch是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTfulAPI让全文搜索变得简单并隐藏Lucene的复杂性。
不过,Elasticsearch不仅仅是Lucene和全文搜索引擎,它还提供:

分布式的实时文件存储,每个字段都被索引并可被搜索

实时分析的分布式搜索引擎

可以扩展到上百台服务器,处理PB级结构化或非结构化数据

而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的RESTfulAPI、各种语言的客户端甚至命令行与之交互。上手Elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。Elasticsearch在Apache2license下许可使用,可以免费下载、使用和修改。
随着知识的积累,你可以根据不同的问题领域定制Elasticsearch的高级特性,这一切都是可配置的,并且配置非常灵活。

以上内容来自[百度百科]

关于ES详细概念见:http://88250.b3log.org/full-text-search-elasticsearch#b3_solo_h3_0

使用C#操作ES

NEST是一个高层的客户端,可以映射所有请求和响应对象,拥有一个强类型查询DSL(领域特定语言),并且可以使用.net的特性比如协变、AutoMappingOfPOCOs,NEST内部使用的依然是Elasticsearch.Net客户端。elasticsearch.net(NEST)客户端提供了强类型查询DSL,方便用户使用,源码下载。

一、如何安装NEST

打开VS的工具菜单,通过NuGet包管理器控制台,输入以下命令安装NEST

Install-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,并指定需要的Attribute

1[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

属性名值类型描述
Analyzerstring分析器名称,值包含standard、simple、whitespace、stop、keyward、pattern、language、snowball、custom等,查看分析器更多信息请点击ElasticsearchAnalyzers
Boostdouble加权值,值越大得分越高
NullValuestring插入文档时,如果数据为NULL时的默认值
IndexFieldIndexOption是否使用分析器,默认使用FieldIndexOption.Analyzed,禁止使用分析器FieldIndexOption.NotAnalyzed
2、NumberAttribute

属性名值类型描述
typeNumberType构造函数参数,指定当前属性的类型,NumberType.Default、Float、Double、Integer、Long、Short、Byte
Boostdouble加权值,值越大得分越高
NullValuedouble插入文档时,如果数据为NULL时的默认值
3、BooleanAttribute

属性名值类型描述
Boostdouble加权值,值越大得分越高
NullValuedouble插入文档时,如果数据为NULL时的默认值
4、DateAttribute

属性名值类型描述
Boostdouble加权值,值越大得分越高
NullValuestring插入文档时,如果数据为NULL时的默认值
Formatstring
5、ObjectAttribute

属性名值类型描述
typestring/Type构造函数参数,指定当前属性的类型T
DynamicDynamicMapping

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);




转载请标明本文来源:http://www.cnblogs.com/yswenli/
更多内容欢迎我的的github:https://github.com/yswenli
如果发现本文有什么问题和任何建议,也随时欢迎交流~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
章节导航