elasticsearch.net项目实战


目录

  • Elasticsearch+kibana

    • 环境搭建

      • windows 10环境配置
      • 安装Elasticsearch
      • head安装(非必需)
      • 安装kibana
    • 基本概念
      • Index
      • Type
      • Document
    • DSL的基本使用
      • 增加
      • 修改
      • 查询
      • 删除
  • Elasticsearch .Net
    • Low level client基本使用
    • 项目实战
  • 总结
  • 参考

     Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最

先进、性能最好的、功能最全的搜索引擎库。

     一说到全文搜索,lucene久负盛名。早年间,因为项目需要,接触过一个叫盘古分词的开源项目,借助其中的分词实现了分词搜索的功能。而盘古分词就是lucence的.NET版本。据说这个开源项目已经恢复更新并支持. NET Core,有兴趣的童鞋可以去围观一下(https://github.com/LonghronShen/Lucene.Net.Analysis.PanGu/tree/netcore2.0)。

      我想很多童鞋都听过ELK,ELK是Elasticsearch、Logstash、Kibana。正好公司运维同事引入了这样一套体系,用于建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。虽然能够从一定程度上解决基本的问题,但是原生的kibana界面和查询方式都不够友好,很难推向广大的开发人员。于是我在想,我们是否可以利用这个开源的库集成到运维自动化平台当中,让这把利剑发挥出更大的价值。

一、环境搭建

 

本文是基于windows 10操作系统的es环境的搭建。

  1. java环境安装

     由于es是java语言开发的,所以这里要安装java环境。

     jdk下载:

https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

     安装完成之后就是配置环境变量:

     查看是否安装成功:

2.安装Elasticsearch

    Elasticsearch版本已经比较多,初学者可能比较懵。特别是在安装head和Kibana的时候,如果版本不匹配,往往会导致无法使用。这里使用的是elasticsearch-5.6.11版本。

     elasticsearch-5.6.11下载:

https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-11

解压到C:\ELk 备用。

3.head安装(非必需)

    es 4.x 版本安装head很简单,只需下载head插件解压到指定目录即可。es 5.x+需要借助node安装。

     head下载:

https://github.com/mobz/elasticsearch-head

解压到C:\ELk\elasticsearch-5.6.11

     node下载:

https://nodejs.org/dist/v8.12.0/node-v8.12.0-win-x64.zip

安装node

检查node和npm是否安装成功

path环境变量末尾 会自动增加 C:\Program Files\nodejs\

安装 phantomjs

官网:http://phantomjs.org/下载【配置环境变量】

安装grunt

npm install -g grunt-cli

执行C:\ELk\elasticsearch-5.6.11\bin\elasticsearch.bat

执行命令启动 head

浏览器访问:http://localhost:9100/

4.安装kibana

    导致为止,其实elasticsearch自身已经安装完成。通过Head就能很方便的操作es,但是kibana集成了head类似功能,并提供了更加友好的访问界面。

     kibana-5.6.9-windows-x86下载:

https://www.elastic.co/downloads/past-releases/kibana-5-6-9

下载之后,解压到C:\ELk\kibana-5.6.9-windows-x86

执行C:\ELk\kibana-5.6.9-windows-x86\bin\kibana.bat

浏览器访问:http://localhost:5601


二、基本概念

  • Cluster(集群)

         集群是一个或多个节点(服务器)的集合,这些节点一起保存整个数据,并在所有节点上提供联合索引和搜索功能。

         一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

          作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。

  • Node(节点)

    节点是集群的一部分、存储数据并参与集群的索引和搜索功能的单个服务器。

  • Index

    索引是具有相似特性的文档集合。

    • 类似于关系型数据库中""的概念
  • Type

    Type是具有一组公共字段的文档定义类型

         例如,假设您运行一个博客平台并将所有数据存储在一个索引中。在该索引中,可以定义用户数据的类型、博客数据的另一种类型以及注释数据的另一种类型。

    • 类似于关系型数据库中""的概念
  • Document

    被索引信息的基本单元。

    • 类似于关系型数据库的一个记录(行)
    • 会被压缩成json格式
  • Shards & Replicas(分片&副本分片)

    索引可以潜在地存储可以超过单个节点的硬件限制的大量数据。例如,占用1TB磁盘空间的十亿个文档的单个索引可能不适合单个节点的磁盘,或者可能太慢而无法单独为来自单个节点的搜索请求提供服务。

         分片的两个主要原因:

    • 它允许您水平分割/缩放您的内容卷。
    • 它允许你分配和并行操作的碎片(可能在多个节点上)从而提高性能/吞吐量

    在网络/云环境中,在任何时候都可以预期到故障,在碎片/节点不知何故脱机或由于任何原因消失的情况下,非常有用,并且强烈建议使用故障转移机制。为此,Elasticsearch允许您将一个或多个索引碎片的副本复制到称为副本碎片(replica shards)或简称为副本(replica)中。

         复制是重要的两个主要原因:

    • 在碎片/节点失败的情况下,它提供了高可用性。由于这个原因,需要注意的是,副本碎片永远不会分配到与原始/主碎片相同的节点上。
    • 它允许您扩展搜索量/吞吐量,因为可以并行地在所有副本上执行搜索。

         添加故障转移

    当集群中只有一个节点在运行时,意味着会有一个单点故障问题——没有冗余。 幸运的是,我们只需再启动一个节点即可防止数据丢失。

         拥有两个节点的集群——所有主分片和副本分片都已被分配。

三、DSL的基本使用

elasticsearch也像mysql一样提供了专门的语法来操作数据。Elasticsearch provides a full Query DSL (Domain Specific Language) based on JSON to define queries.

  • 创建文档
PUT people/person/1?op_type=create
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
  • 修改
POST /user/guest/20/_update
{
"doc": {
"RealName":"LukyHuu20"
}
}
  • 查询
GET /user/guest/_search
{
"query": {
"match": {
"Id":22
}
}
}
  • 删除
DELETE /user/guest/15
{ }

四、Elasticsearch .Net

     elasticsearch是以restfulAPI方式对外提供接口,并提供客户端给多种语言使用。Elasticsearch uses standard RESTful APIs and JSON. We also build and maintain clients in many languages such as Java, Python, .NET, SQL, and PHP. Plus, our community has contributed many more. They’re easy to work with, feel natural to use, and, just like Elasticsearch, don't limit what you might want to do with them.

参考(https://www.elastic.co/products/elasticsearch)

1.Low level client基本使用

     本文是介绍ES的.NET客户端,Elasticsearch .Net - Low level client[5.x]

通过引入对应的版本的客户端,便可通过C#操作ES。参考(https://www.elastic.co/guide/en/elasticsearch/client/net-api/5.x/elasticsearch-net.html)

连接

var settings = new ConnectionConfiguration(new Uri("http://example.com:9200"))
.RequestTimeout(TimeSpan.FromMinutes(2)); var lowlevelClient = new ElasticLowLevelClient(settings);

插入文档

 var indexResponse = lowlevelClient.Index<byte[]>("user", "guest", user.Id.ToString(), user);
byte[] responseBytes = indexResponse.Body;

更新文档

var searchResponse = lowlevelClient.Update<string>("user", "guest", id.ToString(), new
{
doc = new
{
RealName = realname,
Description = description
}
}); bool successful = searchResponse.Success;

查询

var searchResponse = lowlevelClient.Search<string>("user", "guest", new
{
query = new
{
match = new
{
Id = id
}
}
}); bool successful = searchResponse.Success;

删除

var searchResponse = lowlevelClient.Delete<string>("user", "guest", id.ToString());

                bool successful = searchResponse.Success;

2.项目实战

     前面大致介绍了ES的安装和基本使用。那么,如何在项目中落地呢?

使用nuget安装Elasticsearch.Net 5.6.4

Install-Package Elasticsearch.Net -Version 5.6.4

安装完后,

基本的增删该查在项目中的实现上面已经有所介绍,这里重点讲一下查询:

笔者使用的.NET MVC5 Web框架,对于返回的结果笔者做了一个简单封装:


public class ESearchRoot<T>
{
/// <summary>
///
/// </summary>
public int took { get; set; }
/// <summary>
///
/// </summary>
public string timed_out { get; set; }
/// <summary>
///
/// </summary>
public _shards _shards { get; set; }
/// <summary>
///
/// </summary>
public Hits<T> hits { get; set; }
} public class _shards
{
/// <summary>
///
/// </summary>
public int total { get; set; }
/// <summary>
///
/// </summary>
public int successful { get; set; }
/// <summary>
///
/// </summary>
public int skipped { get; set; }
/// <summary>
///
/// </summary>
public int failed { get; set; }
} public class HitsItem<T>
{
/// <summary>
///
/// </summary>
public string _index { get; set; }
/// <summary>
///
/// </summary>
public string _type { get; set; }
/// <summary>
///
/// </summary>
public string _id { get; set; }
/// <summary>
///
/// </summary>
public string _score { get; set; }
/// <summary>
///
/// </summary>
public T _source { get; set; }
/// <summary>
///
/// </summary>
public List<int> sort { get; set; }
/// <summary>
///
/// </summary>
public Highlight highlight { get; set; }
} public class Hits<T>
{
/// <summary>
///
/// </summary>
public int total { get; set; }
/// <summary>
///
/// </summary>
public string max_score { get; set; }
/// <summary>
///
/// </summary>
public List<HitsItem<T>> hits { get; set; }
} public class Highlight
{
/// <summary>
///
/// </summary>
public List<string> Description { get; set; }
}

因为soure返回的对象是不定的,所以使用了泛型。

本项目soure对应的类,user:


///<summary>
///
/// </summary>
public class User
{
/// <summary>
///
/// </summary>
public string Account { get; set; }
/// <summary>
///
/// </summary>
public string Phone { get; set; }
/// <summary>
///
/// </summary>
public string Email { get; set; }
/// <summary>
///
/// </summary>
public string RealName { get; set; }
/// <summary>
///
/// </summary>
public string CanReview { get; set; }
/// <summary>
///
/// </summary>
public string CanExcute { get; set; }
/// <summary>
///
/// </summary>
public string Avatar { get; set; }
/// <summary>
///
/// </summary>
public string IsUse { get; set; }
/// <summary>
///
/// </summary>
public int Id { get; set; }
/// <summary>
///
/// </summary>
public string Name { get; set; }
/// <summary>
///
/// </summary>
public string Description { get; set; }
/// <summary>
///
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
///
/// </summary>
public DateTime ModifyTime { get; set; }
}

项目使用了带条件的分页查询:

public List<AdminUser> GetBySomeWhere(string keyword, int limit, int pageSize, out int total)
{
List<AdminUser> users = new List<AdminUser>(); total = 0;
try
{
var settings = new ConnectionConfiguration(new Uri("http://localhost:9200/"))
.RequestTimeout(TimeSpan.FromMinutes(2)); var lowlevelClient = new ElasticLowLevelClient(settings); //根据不同的参数 来构建不同的查询条件
var request = new object();
if (!String.IsNullOrEmpty(keyword))
{
request = new
{
from = limit,
size = pageSize,
query = new
{
match = new
{
Description = keyword
}
},
highlight = new
{
fields = new
{
Description = new { }
}
},
sort = new
{
Id = new
{
order = "desc"
}
}
};
}
else
{
request = new
{
from = limit,
size = pageSize,
query = new
{
match_all = new
{ }
},
highlight = new
{
fields = new
{
Description = new { }
}
},
sort = new
{
Id = new
{
order = "desc"
}
}
};
} var searchResponse = lowlevelClient.Search<string>("user", "guest", request); bool successful = searchResponse.Success;
var responseJson = searchResponse.Body; if (!successful)
{
return users;
} ESearchRoot<User> root = JsonHelper.JSONStringObject<ESearchRoot<User>>(responseJson);
if (root != null)
{
total = root.hits.total;
foreach (HitsItem<User> item in root.hits.hits)
{
if (item._source != null)
{
string highlightDescription = String.Empty;
StringBuilder sbDs = new StringBuilder();
if (item.highlight != null && item.highlight.Description.Count > 0)
{
//ighlightDescription = item.highlight.Description[0];
foreach (var d in item.highlight.Description)
{
sbDs.Append(d);
}
highlightDescription = sbDs.ToString();
} AdminUser user = new AdminUser
{
Id = item._source.Id,
RealName = item._source.RealName,
Account = item._source.Account,
Email = item._source.Email,
Phone = item._source.Phone,
//IsUse=item._source.IsUse,
Avatar = item._source.Avatar,
Description = item._source.Description,
HighlightDescription = highlightDescription,
CreateTime = item._source.CreateTime,
ModifyTime = item._source.ModifyTime
};
users.Add(user);
}
}
} return users;
}
catch (ElasticsearchClientException ex)
{
//Log4Helper.Error
}
return users;
}

项目最终的效果如下:

五、总结

     elasticsearch是很强大的开源工具,在实现全文搜索上有其独到之处,也是大数据的分析方面利器,值得大家深入去研究和实践。

六、参考


Elasticsearch.net项目实战的更多相关文章

  1. Elasticsearch.net项目

    Elasticsearch.net项目实战 https://www.cnblogs.com/lucky_hu/p/9746736.html elasticsearch.net项目实战 @智客幸达 目录 ...

  2. SpringBoot电商项目实战 — ElasticSearch接入实现

    如今在一些中大型网站中,搜索引擎已是必不可少的内容了.首先我们看看搜索引擎到底是什么呢?搜索引擎,就是根据用户需求与一定算法,运用特定策略从互联网检索出制定信息反馈给用户的一门检索技术.搜索引擎依托于 ...

  3. 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战

    大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...

  4. ELKStack-生产案例项目实战(十一)

    ELKStack-生产案例项目实战 1.收集ES和apache日志,入redis input { file { path => "/etc/httpd/logs/access_log& ...

  5. [elk]logstash的最佳实战-项目实战

    重点参考: http://blog.csdn.net/qq1032355091/article/details/52953837 不得不说这是一个伟大的项目实战,是正式踏入logstash门槛的捷径 ...

  6. 从0使用Ruby on Rails打造企业级RESTful API项目实战之我的云音乐

    本节对我们项目实现的功能和知识点做一个简单的介绍,因为是RESTful API项目,所以对于后端来说基本上没有什么UI界面可展示,那我们就在关键的点,使用客户端(Android)实现的效果图. 课程简 ...

  7. Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构

    Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...

  8. JavaEE在职加薪课好客租房项目实战视频教程

    JavaEE在职加薪课好客租房项目实战视频教程课程介绍:       本课程采用SOA架构思想进行设计,基于目前主流后端技术框架SpringBoot.SpringMVC.Mybaits.Dubbo等来 ...

  9. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

随机推荐

  1. python 错误记录

    class Func: d = dict() def __setitem__(self, key, value): # xxx object does not support item assignm ...

  2. Android第一次作业

    Android第一次作业——天气预报界面 成果图: 思路: 运用RelativeLayout布局管理器来设计整体布局,在其中插入需要的图片和文本框,并设置其字体格式和背景.最后用HorizontalS ...

  3. DevExpress XtraTabbedMdiManager删除Page

    DevExpress XtraTabbedMdiManager删除Page 时,xtraTabbedMdiManager1.Pages.Remove()是没用的. 正确的应该是xtraTabbedMd ...

  4. centos7zabbix-agen安装

    安装包下载地址:http://www.zabbix.com/download.php 下载对应rpm包     http://repo.zabbix.com/zabbix/ wget http://r ...

  5. js高级3

    1.解决函数内this的指向 可以在函数外提前声明变量_this/that=this 通过apply和call来修改函数内的this指向 (1)二者区别 用法是一样的,就是参数形式不一样        ...

  6. sublime text3 在 14.04.1-Ubuntu 下的中文输入

    1.安装 fcitx sudo add-apt-repository ppa:fcitx-team/nightly // 添加FCITX仓库. sudo apt-get update // 更新仓库. ...

  7. python制作词云

    需要模块wordcloud,pip install wordcloud安装即可.代码: , #边距background_color='black',#指定背景颜色font_path='simhei.t ...

  8. 回顾4180天在腾讯使用C#的历程,开启新的征途

    今天是2018年8月8日,已经和腾讯解除劳动关系,我的公司正式开始运营,虽然还有很多事情需要理清,公司官网也没有做,接下来什么事情都需要自己去完成了,需要一步一个脚印去完善,开启一个新的征途,我将在博 ...

  9. Mycat适合场景及不适合场景

    1.非分片字段查询 Mycat中的路由结果是通过分片字段和分片方法来确定的.例如下图中的一个Mycat分库方案: 根据 tt_waybill 表的 id 字段来进行分片 分片方法为 id 值取 3 的 ...

  10. Git漏洞允许任意代码执行(CVE-2018-17456)复现

    Git漏洞允许任意代码执行(CVE-2018-17456) 国外安全研究员 joernchen 在 9 月 23 日向 git 官方报告了漏洞的相关细节.10月5日,Git项目披露了一个漏洞,编号为C ...