Elasticsearch简介

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

但是,Lucene只是一个库。想要发挥其强大的作用,你需使用C#将其集成到你的应用中。Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。

Elasticsearch是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTful API让全文搜索变得简单并隐藏Lucene的复杂性。

不过,Elasticsearch不仅仅是Lucene和全文搜索引擎,它还提供:

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

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

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

而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的RESTful API、各种语言的客户端甚至命令行与之交互。

上手Elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。Elasticsearch在Apache 2 license下许可使用,可以免费下载、使用和修改。

随着知识的积累,你可以根据不同的问题领域定制Elasticsearch的高级特性,这一切都是可配置的,并且配置非常灵活。

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

关于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,方便用户使用,源码下载。(https://github.com/elastic/elasticsearch-net/releases/tag/2.4.4)

一、如何安装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更有优势,比如支持负载均衡、故障转移等。

通过单点链接:

var node = new Uri("http://myserver:9200");

var settings = new ConnectionSettings(node);

var client = new ElasticClient(settings);

通过连接池链接:

var nodes = new Uri[]

{

new Uri("http://myserver1:9200"),

new Uri("http://myserver2:9200"),

new Uri("http://myserver3:9200")

};

var pool = new StaticConnectionPool(nodes);

var settings = new ConnectionSettings(pool);

var client = new ElasticClient(settings);

NEST Index

为了知道请求需要操作哪个索引,Elasticsearch API期望收到一个或多个索引名称作为请求的一部分。

一、指定索引

1、可以通过ConnectionSettings使用.DefaultIndex(),来指定默认索引。当一个请求里没有指定具体索引时,NEST将请求默认索引。

var settings = new ConnectionSettings()

.DefaultIndex("defaultindex");

2、可以通过ConnectionSettings使用.MapDefaultTypeIndices(),来指定被映射为CLR类型的索引。

var settings = new ConnectionSettings()

.MapDefaultTypeIndices(m => m

.Add(typeof(Project), "projects")

);

注意:通过.MapDefaultTypeIndices()指定索引的优先级要高于通过.DefaultIndex()指定索引,并且更适合简单对象(POCO)

3、另外还可以显示的为请求指定索引名称,例如:

var response = client.Index(student, s=>s.Index("db_test"));

var result = client.Search<Student>(s => s.Index("db_test"));

var result = client.Delete<Student>(null, s => s.Index("db_test"));

……

注意:当现实的为请求指定索引名称时,这个优先级是最高的,高于以上两种方式指定的索引。

4、一些Elasticsearch API(比如query)可以采用一个、多个索引名称或者使用_all特殊标志发送请求,请求NEST上的多个或者所有节点

//请求单一节点

var singleString = Nest.Indices.Index("db_studnet");

var singleTyped = Nest.Indices.Index<Student>();

ISearchRequest singleStringRequest = new SearchDescriptor<Student>().Index(singleString);

ISearchRequest singleTypedRequest = new SearchDescriptor<Student>().Index(singleTyped);

//请求多个节点

var manyStrings = Nest.Indices.Index("db_studnet", "db_other_student");

var manyTypes = Nest.Indices.Index<Student>().And<OtherStudent>();

ISearchRequest manyStringRequest = new SearchDescriptor<Student>().Index(manyStrings);

ISearchRequest manyTypedRequest = new SearchDescriptor<Student>().Index(manyTypes);

//请求所有节点

var indicesAll = Nest.Indices.All;

var allIndices = Nest.Indices.AllIndices;

ISearchRequest indicesAllRequest = new SearchDescriptor<Student>().Index(indicesAll);

ISearchRequest allIndicesRequest = new SearchDescriptor<Student>().Index(allIndices);

二、创建索引

Elasticsearch API允许你创建索引的同时对索引进行配置,例如:

var descriptor = new CreateIndexDescriptor("db_student")

.Settings(s => s.NumberOfShards(5).NumberOfReplicas(1));

client.CreateIndex(descriptor);

这里指定了该索引的分片数为5、副本数为1。

三、删除索引

Elasticsearch API允许你删除索引,例如:

var descriptor = new DeleteIndexDescriptor("db_student").Index("db_student");

client.DeleteIndex(descriptor)

这里制定了要删除的索引名称“db_student”,以下为更多删除用例:

//删除指定索引所在节点下的所有索引

var descriptor = new DeleteIndexDescriptor("db_student").AllIndices();

NEST Mapping

NEST提供了多种映射方法,这里介绍下通过Attribute自定义映射。

一、简单实现

1、定义业务需要的POCO,并指定需要的Attribute

[ElasticsearchType(Name = "student")]

public class Student

{

[Nest.String(Index = FieldIndexOption.NotAnalyzed)]

public string Id { get; set; }

[Nest.String(Analyzer = "standard")]

public string Name { get; set; }

[Nest.String(Analyzer = "standard")]

public string Description { get; set; }

public DateTime DateTime { get; set; }

}

2、接着我们通过.AutoMap()来实现映射

var descriptor = new CreateIndexDescriptor("db_student")

.Settings(s => s.NumberOfShards(5).NumberOfReplicas(1))

.Mappings(ms => ms

.Map<Student>(m => m.AutoMap())

);

client.CreateIndex(descriptor);

注意:通过.Properties()可以重写通过Attribute定义的映射

二、Attribute介绍

1、StringAttribute

2、NumberAttribute

3、BooleanAttribute

属性名 值类型 描述
Boost double 加权值,值越大得分越高
NullValue double 插入文档时,如果数据为NULL时的默认值

4、DateAttribute

属性名 值类型 描述
Boost double 加权值,值越大得分越高
NullValue string 插入文档时,如果数据为NULL时的默认值
Format string  

5、ObjectAttribute

属性名 值类型 描述
type string/Type 构造函数参数,指定当前属性的类型T
Dynamic DynamicMapping  

NEST Search

NEST提供了支持Lambda链式query DLS(领域特定语言)方式,以下是简单实现及各个query的简述。

一、简单实现

1、定义SearchDescriptor,方便项目中复杂业务的实现

var query = new Nest.SearchDescriptor<Models.ESObject>();

var result = client.Search<Student>(x => query)

2、检索title和content中包含key,并且作者不等于“wenli”的文档

query.Query(q =>

q.Bool(b =>

b.Must(m =>

m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content)).Query(key))

)

.MustNot(m =>

m.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli"))

)

)

);

注意:

如果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、过滤作者等于“wenli”的文档

query.PostFilter(x => x.Term(t => t.Field(obj => obj.Author).Value("wenli")));

4、过滤作者等于“wenli”或者等于“yswenli”的文档,匹配多个作者中间用空格隔开

query.PostFilter(x => x.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("wenli yswenli")));

5、过滤数量在1~100之间的文档

query.PostFilter(x => x.Range(t => t.Field(obj => obj.Number).GreaterThanOrEquals(1).LessThanOrEquals(100)));

6、排序,按照得分倒叙排列

query.Sort(x => x.Field("_score", Nest.SortOrder.Descending));

7、定义高亮样式及字段

query.Highlight(h => h

.PreTags("<b>")

.PostTags("</b>")

.Fields(

f => f.Field(obj => obj.Title),

f => f.Field(obj => obj.Content),

f => f.Field("_all")

)

);

8、拼装查询内容,整理数据,方便前段调用

var list = result.Hits.Select(c => new Models.ESObject()

{

Id = c.Source.Id,

Title = c.Highlights == null ? c.Source.Title : c.Highlights.Keys.Contains("title") ? string.Join("", c.Highlights["title"].Highlights) : c.Source.Title, //高亮显示的内容,一条记录中出现了几次

Content = c.Highlights == null ? c.Source.Content : c.Highlights.Keys.Contains("content") ? string.Join("", c.Highlights["content"].Highlights) : c.Source.Content, //高亮显示的内容,一条记录中出现了几次

Author = c.Source.Author,

Number = c.Source.Number,

IsDisplay = c.Source.IsDisplay,

Tags = c.Source.Tags,

Comments = c.Source.Comments,

DateTime = c.Source.DateTime,

})

二、query DSL介绍 

elasticsearch.net Document

文档操作包含添加/更新文档、局部更新文档、删除文档及对应的批量操作文档方法。

一、添加/更新文档及批量操作

添加/更新单一文档

Client.Index(student);

批量添加/更新文档

var list = new List<Student>();

client.IndexMany<Student>(list);

二、局部更新单一文档及批量操作

局部更新单一文档

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

三、删除文档及批量操作

删除单一文档

client.Delete<Student>("001");

批量删除文档

var ids = new List<string>() { "001", "002" };

var bulkQuest = new BulkRequest() { Operations = new List<IBulkOperation>() };

foreach (var v in ids)

{

bulkQuest.Operations.Add(new BulkDeleteOperation<Student>(v));

}

var result = client.Bulk(bulkQuest);

转至: cnblogs.com/yswenli/p/6266569.html

C# 如何使用 Elasticsearch (ES)的更多相关文章

  1. elasticsearch(es) 集群恢复触发配置(Local Gateway参数)

    elasticsearch(es) 集群恢复触发配置(Local Gateway) 当你集群重启时,几个配置项影响你的分片恢复的表现. 首先,我们需要明白如果什么也没配置将会发生什么. 想象一下假设你 ...

  2. 【转载】[Elasticsearch]ES入门

    传送门:http://www.cnblogs.com/xing901022 ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的 ...

  3. Elasticsearch(ES) 下载&安装

    欢迎关注笔者的公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site/ ...

  4. solr和ElasticSearch(ES)的区别?

    Solr2004年诞生 ElasticSearch 2010年诞生 ES更新 ElasticSearch简介: ElasticSearch是一个实时的分布式的搜索引擎和分析引擎.它可以帮助你用前所未有 ...

  5. Elasticsearch ES索引

    ES是一个基于RESTful web接口并且构建在Apache Lucene之上的开源分布式搜索引擎. 同时ES还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,能够横向 ...

  6. ELK之 elasticsearch ES集群 head安装

    最近项目用到 jenkins  ELK  也在一次重新学习了一次  jenkins 不用说了 玩得就是  插件   +  base---shell ,  ELK  这几年最流得log收集平台,当然不止 ...

  7. ElasticSearch(ES)使用Nested结构存储KV及聚合查询

    自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客同步发表文章,为了更好的阅读体验,建议您移步至我的博客 本文作者: Jeffrey 本文链接: https://w ...

  8. 十一、.net core(.NET 6)搭建ElasticSearch(ES)系列之ElasticSearch、head-master、Kibana环境搭建

    搭建ElasticSearch+Kibana环境 前提条件:已经配置好JDK环境以及Nodejs环境.如果还未配置,请查看我的上一篇博客内容,有详细配置教程. 先下载ElasticSearch(以下文 ...

  9. 十四、.net core(.NET 6)搭建ElasticSearch(ES)系列之给ElasticSearch添加SQL插件和浏览器插件

     给ES添加SQL插件的方法: 下载SQL插件地址:https://github.com/NLPchina/elasticsearch-sql 当前最新的是7.12版本,我的ES是7.13版本,暂且将 ...

  10. 十八、.net core(.NET 6)搭建ElasticSearch(ES)系列之使用Logstash通过Rabbitmq接收Serilog日志到ES

    使用Logstash通过Rabbitmq接收Serilog日志到ES 首先,要部署logstash 为了与前面的ElasticSearch版本保持一致,此处Logstash下载的版本也是7.13.1, ...

随机推荐

  1. Java核心技术及面试指南面试题,基本数据类型、封装类和运算操作的面试题

    2.1.5.1说说&和&&的区别,以及|与||的区别. &和|是位运算符,不怎么用,而&&和||是逻辑运算符,一般用在if,while,for等条件判断 ...

  2. VueJs(11)---vue-router(命名路由,命名视图,重定向别名,路由组件传参)

    vue-router 上篇文章讲了第一篇vue-router相关文章,文章地址:VueJs(10)---vue-router(进阶1) 一.命名路由 有时候,通过一个名称来标识一个路由显得更方便一些, ...

  3. 微软新动向之Android和IOS应用 visual studio 2015 Cordova[原创]

    自萨蒂亚·纳德拉(Satya Nadella)上任微软CEO以来,可谓是惊喜不断,仿佛让世界尤其是我们.net程序员心中又燃起了希望.先是免费提供 iOS 版和安卓版 Office:然后在 xbox ...

  4. springboot Aop 统一处理Web请求日志

    1.增加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  5. 用js如何获取file是否存在

    其实注意点就可以知道了. 举个例子 firebug看出这代码: <div id="SWFUpload_0_0" class="uploadify-queue-ite ...

  6. Apache-Flink深度解析-SQL概览

    你可能感兴趣的文章: Flink入门 Flink DataSet&DataSteam API Flink集群部署 Flink重启策略 Flink分布式缓存 Flink重启策略 Flink中的T ...

  7. js forEach跳出循环

    假设当我们只需知道某个数组有没有某个属性,如果找到了直接跳出循环,省略掉剩下的循环步骤是较优化的操作,但是for中是可以利用break跳出循环,但break在forEach中无效,那么forEach能 ...

  8. 一张图,让你和面试官聊一个小时的“Java内存模型”

    如果面试官问你:你了解 Java 内存模型吗? 你就可以使用这张图,按照这张图中的顺序和面试官开聊,正常情况下,聊一个小时是差不多的,这个时候,对你的处境是非常有益的,因为面试官的时间不多了.

  9. js_ajax模拟form表单提交_多文件上传_支持单个删除

    需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中: 问题:由于只有一个file ...

  10. AngularJS_自定义控件_笔记1

    简介: 本篇博客是在学习AngularJS自定义控件的学习记录,作为一个学习示例... A-基本架构介绍 新建一个AngularJs的项目,大概项目结构如下: 项目结构: 大概是由:app.js,bo ...