Version:5.xhtml
英文原文地址:Getting startedc#
说实话,这篇文章翻译的很糟糕。可是个人能力有限,目前只有这个水平,还望各位多指导。api
NEST 是 Elasticsearch 的一个高层级的 .NET 客户端,可是它仍然很是接近原始的 Elasticsearch API 。NEST 中全部的请求和响应都是经过类型公开的,这使得它能够快速地启动和运行。服务器
在美丽的外表之下,NEST 有着一个强大的低层级的核心 - Elasticsearch.Net 。有了这个核心,NEST 才得以(向 Elasticsearch 本体服务程序)发送请求和接收响应。这个过程当中,NEST 使用和扩展了 Elasticsearch.NET 的许多类型。另外,NEST 公开了这个低级客户端,你能够经过 .LowLevel 属性来访问。异步
链接位于 http://localhost:9200
的本地 Elasticsearch 是很是简单的,你只须要实例化一个客户端的实例便可。async
var client = new ElasticClient();
一般状况下,你会须要向客户端传递一些额外的配置选项。好比:你的 Elasticsearch 在远程服务器上运行,那你就须要传递它的具体地址。 ConnectionSettings
参数就是来接收这些配置信息的,有了它你就能够根据不一样的配置实例化出相应的客户端。elasticsearch
var settings = new ConnectionSettings(new Uri("http://example.com:9200")) .DefaultIndex("people"); var client = new ElasticClient(settings);
仔细看上面这个例子,咱们设置了一个默认索引。若是请求中没有明确提供其余索引,而且没法从 POCO 泛型参数中推断出索引,就会使用这个默认索引。ConnectionSettings
继承自 ConnnectionConfiguraion
,Elasticsearch.NET (那个低层级的客户端)经过这个对象来接收额外的配置选项。了解更多的配置选项,请访问 Configuration options 。ide
注意,若是没有配置默认索引,而 NEST 又没法从请求中推断出索引,那它就会抛出一个异常。函数
ConnectionSettings
没有严格要求只能向 Elasticsearch 传递一个地址。NEST 中还提供了几种不一样类型的链接池用来配置客户端。下面的栗子使用了一个 SniffingConnectionPool
,它包含了集群中 3 个 Elasticsearch 节点的地址。客户端将使用这种链接池来维护一个集群中可用节点的列表,这样即可以用循环的方式发送请求。布局
var uris = new[] { new Uri("http://localhost:9200"), new Uri("http://localhost:9201"), new Uri("http://localhost:9202"), }; var connectionPool = new SniffingConnectionPool(uris); var settings = new ConnectionSettings(connectionPool) .DefaultIndex("people"); var client = new ElasticClient(settings);
将客户端配置好并链接上 Elasticsearch 以后,咱们须要往集群里存储一些数据。
假设咱们有以下简单传统CLR对象(Plain Old CLR Object)
public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
使用同步或者异步的方式索引一个 POCO 实例
var person = new Person { Id = 1, FirstName = "Martijn", LastName = "Laarman" }; var indexResponse = client.Index(person); (1) var asyncIndexResponse = await client.IndexAsync(person); (2)
(1) 同步方法返回一个 IIndexResponse
对象
(2) 异步方法返回一个可等待的 Task<IIndexResponse>
对象
注意:NEST 中全部的方法都提供了同步和异步两种版本,异步方法使用 *Async 后缀命名
上述代码会将文档索引到 /people/person/1
。NEST 很聪明,它会根据 Person 的 CLR 类型来推断 type
,并根据 POCO 的 Id
属性来推断文档的 id
。了解 NEST 中推断文档 id
的其余方式,请参阅 Ids inference 。ConnectionSettings
中配置的默认索引会被用来看成请求的索引名。
警告:NEST 会将 POCO 序列化为 JSON 文档发送给 Elasticsearch。默认状况下,在执行序列化时,NEST 将 POCO 的属性名转换成驼峰式字符串。你可使用
ConnectionSettings
的.DefaultFieldNameInferrer(Func<string,string>)
方法来改变这一行为。
咱们已经索引了一些文档,接下来就能够开始查询了。
var searchResponse = client.Search<Person>(s => s .From(0) .Size(10) .Query(q => q .Match(m => m .Field(f => f.FirstName) .Query("Martijn") ) ) ); var people = searchResponse.Documents;
people
变量如今保存着名字里包含 Martijn 的前十我的的文档。这个查询的搜索终端是 /people/person/_search
,其中索引名由 ConnectionSettings
中的默认索引肯定,类型名由搜索时传递的泛型参数 Person
肯定。
使用 .AllTypes()
能够搜索索引内的所有类型
var searchResponse = client.Search<Person>(s => s .AllTypes() .From(0) .Size(10) .Query(q => q .Match(m => m .Field(f => f.FirstName) .Query("Martijn") ) ) );
请求中能够提供单个或者多个索引和类型名,了解更多请分别参阅 Indices paths 和 Document paths 。
到目前为止,全部的搜索示例都使用了 NEST 的 Fluent API ,它使用 lambda 表达式构造结构化的查询,这一点模仿了 Elasticsearch 中的 Query DSL 的查询结构。
NEST 还公开了一个对象初始值设定语法,对于那些不热衷于深层嵌套子表达式的开发者,能够用这种方式来构造查询(布局是关键 ~)
这里有个和以前的栗子相同的查询,不过改为了使用对象初始值设定语法来构造查询
var searchRequest = new SearchRequest<Person>(Nest.Indices.All, Types.All) (1) { From = 0, Size = 10, Query = new MatchQuery { Field = Infer.Field<Person>(f => f.FirstName), Query = "Martijn" } }; var searchResponse = await client.SearchAsync<Person>(searchRequest);
(1) 全部的索引和类型,都在构造函数中指定
笔记:本文开始的时候提到过,高层客户端经过
.LowLevel
属性公开了Elasticsearch.NET
的低层客户端。有些状况下,低层客户端会更合适。例如:你已经有了一个 JSON 对象,想直接发送给服务器,而不但愿再把它转换成 Fluent API 或者 Object Initializer 语法。又或者说,高层客户端有一个 bug,让你不得不选择低层客户端。使用低层客户端,能够经过发送字符串或者匿名类型的请求来完成工做。经过
.LowLevel
来使用低层客户端,你可使用 NEST 中全部的强类型和序列化功能这里有个示例:
var searchResponse = client.LowLevel.Search<SearchResponse<Person>>("people", "person", new { from = 0, size = 10, query = new { match = new { field = "firstName", query = "Martijn" } } }); var responseJson = searchResponse.Body;能够看到,请求是一个匿名类型,可是响应体是 NEST 返回的响应类型的具体实现。
除告终构化和非结构化的查询,Elasticsearch 还支持聚合数据
var searchResponse = await client.SearchAsync<Person>(s => s .Size(0) .Query(q => q .Match(m => m .Field(f => f.FirstName) .Query("Martijn") ) ) .Aggregations(a => a .Terms("last_names", ta => ta .Field(f => f.LastName) ) ) ); var termsAggregation = searchResponse.Aggs.Terms("last_names");
这个例子里,match
查询搜索出了名字里有 "Martijn" 的人,这和以前的例子是同样的,不一样的是:
0
,由于咱们不须要查到的前 10 份文档,咱们只对聚合结果感兴趣terms
聚合,从而将搜索结果按照姓氏分组termsAggregation
能够用于获取每一个桶的文档数量,其中每一个桶的键是姓氏。更多信息,请参阅 Writing aggregations