一起来学EleasicSearch

Elasticsearch简介

Elasticsearch是一个实时分布式搜索和分析引擎。它让你以前所未有的速度处理大数据成为可能。
它用于全文搜索、结构化搜索、分析以及将这三者混合使用:
维基百科使用Elasticsearch提供全文搜索并高亮关键字,以及输入实时搜索(search-asyou-type)和搜索
纠错(did-you-mean)等搜索建议功能。
英国卫报使用Elasticsearch结合用户日志和社交网络数据提供给他们的编辑以实时的反馈,以便及时了
解公众对新发表的文章的回应。
StackOverflow结合全文搜索与地理位置查询,以及more-like-this功能来找到相关的问题和答案。
Github使用Elasticsearch检索1300亿行的代码。
但是Elasticsearch不仅用于大型企业,它还让像DataDog以及Klout这样的创业公司将最初的想法变成可
扩展的解决方案。
Elasticsearch可以在你的笔记本上运行,也可以在数以百计的服务器上处理PB级别的数据 。
Elasticsearch是一个基于Apache Lucene™的开源搜索引擎。无论在开源还是专有领域,Lucene可以
被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。

但是,Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用
中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是
通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单

Solr简介

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了
比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化
Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST
方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xml文档添加、删除、更新索引
。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织
页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运
行情况。
solr是基于lucene开发企业级搜索服务器,实际上就是封装了lucene。
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过
http请求,向搜索引擎服务器提交一定格式的文件,生成索引;也可以通过提出查找请求,并得到返回
结果。

Lucene简介
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具
包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引
引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单
易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索
引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提
供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的
免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们
经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。
Lucene是一个全文检索引擎的架构。那什么是全文搜索引擎?
全文搜索引擎是名副其实的搜索引擎,国外具代表性的有Google、Fast/AllTheWeb、AltaVista、
Inktomi、Teoma、WiseNut等,国内著名的有百度(Baidu)。它们都是通过从互联网上提取的各个网
站的信息(以网页文字为主)而建立的数据库中,检索与用户查询条件匹配的相关记录,然后按一定的
排列顺序将结果返回给用户,因此他们是真正的搜索引擎。
从搜索结果来源的角度,全文搜索引擎又可细分为两种,一种是拥有自己的检索程序(Indexer),俗称
“蜘蛛”(Spider)程序或“机器人”(Robot)程序,并自建网页数据库,搜索结果直接从自身的数据库中
调用,如上面提到的7家引擎;另一种则是租用其他引擎的数据库,并按自定的格式排列搜索结果,如
Lycos引擎。

Elasticsearch和Solr比较

  1. es基本是开箱即用(解压就可以用 ! ),非常简单。Solr安装略微复杂一丢丢!
  2. Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能。
  3. Solr 支持更多格式的数据,比如JSON、XML、CSV,而 Elasticsearch 仅支持json文件格式。
  4. Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提
    供,例如图形化界面需要kibana友好支撑~!
  5. Solr 查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用;
    ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。
    Solr 是传统搜索应用的有力解决方案,但 Elasticsearch 更适用于新兴的实时搜索应用。
  6. Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而 Elasticsearch相对开发维护者
    较少,更新太快,学习使用成本较高。(趋势!)

ElasticSearch安装

  1. 官网下载:官网
  2. 解压缩
  3. bin目录下运行elasticsearch.bat

安装Kibana

Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索
引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理
解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch查
询动态。设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动
Elasticsearch索引监测。

官网:官网

同样是开箱即用。 注意ES和Kibana版本对应
解压缩,需要先运行EleasicSearch,然后运行bin目录下kibana.bat。

配置中文汉化:
打开config目录下的kibana.yml在最后加上下面代码:

i18n.locale: "zh-CN"

ES核心概念

1、索引
2、字段类型(mapping)
3、文档(documents)

概述

elasticsearch是面向文档,关系行数据库 和 elasticsearch 客观的对比!一切都是JSON!

Relational DB          Elasticsearch
数据库(database)         索引(indices)
表(tables)                 types
行(rows)                   documents
字段(columns)              fields

Rest风格说明

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交
互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
基本Rest命令说明:

method           url地址                                    描述
PUT     localhost:9200/索引名称/类型名称/文档id        创建文档(指定文档id)
POST    localhost:9200/索引名称/类型名称 创建文档      (随机文档id)
POST    localhost:9200/索引名称/类型名称/文档id/_update   修改文档
DELETE  localhost:9200/索引名称/类型名称/文档id           删除文档
GET     localhost:9200/索引名称/类型名称/文档id           查询文档通过文档id
POST    localhost:9200/索引名称/类型名称/_search         查询所有数

关于索引的基本操作

1、创建一个索引!

PUT /索引名/~类型名~/文档id {请求体}

例如:

PUT /text1/type1/1
{
  "name":"马文博",
  "age":3
}

然后我们可以在kibana中添加此索引就可以查看字段

关于文档的基本操作(重点)

基本操作

1.添加数据

PUT /text1/type1/3
{
  "name":"MRyan",
  "age":3,
  "tags": ["技术宅","排球","程序员"]
}

2.获取数据 GET

GET text1/type1/3

3.更新数据 PUT

PUT /text1/type1/3
{
  "name":"MRyan",
  "age":3,
  "tags": ["技术宅","排球","帅哥"]
}

其中"_version" : 2,代表被改动的次数

4.Post _update , 推荐使用这种更新方式!

POST /text1/type1/3/_update
{
 "doc":{
   "name":"HELLO"
 }
}

5.简单搜索

GET text1/type1/3

或者这样:

GET text1/type1/_search?q=name:HELLO

其中结果中"_score" : 1.6943598,代表匹配度,匹配度越高分值越高。

6.复杂操作搜索

GET text1/type1/_search
{
  "query": {
    "match": {
      "name": "HELLO"
    }
  }
}

结果的过滤

GET text1/type1/_search
{
  "query": {
    "match": {
      "name": "HELLO"
    }
  }
  , "_source": "name"
}

结果集

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.6931471,
    "hits" : [
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "3",
        "_score" : 0.6931471,
        "_source" : {
          "name" : "HELLO"
        }
      }
    ]
  }
}

7.排序

先添加两个数据

PUT /text1/type1/5
{
  "name":"马文博",
  "age":10

}
 PUT /text1/type1/6
    {
      "name":"马文博2",
      "age":22
    
    }

根据年龄降序排序

GET text1/type1/_search
{
  "query": {
    "match": {
      "name": "马文博"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

8.分页查询

GET text1/type1/_search
{
  "query": {
    "match": {
      "name": "马文博"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,//从第几个数据开始
  "size": 1//返回多少条数据
}

9.布尔值查询 must(and)查询 类似于where name = xxx and age= xxx

GET text1/type1/_search
{
  "query": {
  "bool": {
    "must": [
      {
        "match": {
          "name": "马文博2"
        }
      }
      ,
      {
        "match": {
          "age": "10"
        }
      }
    ]
  }
  }
}

结果集:

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.2578812,
    "hits" : [
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "6",
        "_score" : 3.2578812,
        "_source" : {
          "name" : "马文博2",
          "age" : 10
        }
      }
    ]
  }
}

10.布尔值查询 should(or)类似于 where name= xxx or age= xxx

GET text1/type1/_search
{
  "query": {
  "bool": {
    "should": [
      {
        "match": {
          "name": "马文博2"
        }
      }
      ,
      {
        "match": {
          "age": "10"
        }
      }
    ]
  }
  }
}

结果集:

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 4.341042,
    "hits" : [
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "6",
        "_score" : 4.341042,
        "_source" : {
          "name" : "马文博2",
          "age" : 10
        }
      },
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "5",
        "_score" : 2.6701894,
        "_source" : {
          "name" : "马文博",
          "age" : 22
        }
      }
    ]
  }
}
  1. must_not (not)
    ==================

查询姓名不是马文博的数据

GET text1/type1/_search
{
  "query": {
  "bool": {
    "must_not": [
      {
        "match": {
          "name": "马文博"
        }
      }
    ]
  }
  }
}

12.高亮查询

GET text1/type1/_search
{
  "query": {
  "bool": {
    "must": [
      {
        "match": {
          "name": "马文博2"
        }
      },
      {
        "match": {
          "age": "10"
        }
      }
    ]
  }
  },
  "highlight": {
    "fields": {
      "name":{}
    }
  }
}

结果集:

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 34,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 4.341042,
    "hits" : [
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "6",
        "_score" : 4.341042,
        "_source" : {
          "name" : "马文博2",
          "age" : 10
        },
        "highlight" : {
          "name" : [
            "<em>马</em><em>文</em><em>博</em><em>2</em>"//高亮显示
          ]
        }
      }
    ]
  }
}

13.自定义高亮条件

GET text1/type1/_search
{
  "query": {
  "bool": {
    "must": [
      {
        "match": {
          "name": "马文博2"
        }
      },
      {
        "match": {
          "age": "10"
        }
      }
    ]
  }
  },
  "highlight": {
    "pre_tags": "<p class='id' style='color:yellow'>", 
    "post_tags": "</p>", 
    "fields": {
      "name":{}
    }
  }
}

结果集:

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 4.341042,
    "hits" : [
      {
        "_index" : "text1",
        "_type" : "type1",
        "_id" : "6",
        "_score" : 4.341042,
        "_source" : {
          "name" : "马文博2",
          "age" : 10
        },
        "highlight" : {
          "name" : [
            "<p class='id' style='color:yellow'>马</p><p class='id' style='color:yellow'>文</p><p class='id' style='color:yellow'>博</p><p class='id' style='color:yellow'>2</p>"
          ]
        }
      }
    ]
  }
}

IK分词器插件

什么是IK分词器?
分词:即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把
数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个
词,比如 “我爱狂神” 会被分为"我",“爱”,“狂”,“神”,这显然是不符合要求的,所以我们需要安装中文分词
器ik来解决这个问题。
如果要使用中文,建议使用ik分词器!
IK提供了两个分词算法:ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细
粒度划分!一会我们测试!

安装

下载地址
下载完毕之后,放入到我们的elasticsearch 插件目录下即可!
注意版本对应 目前ik分词器支持ES7.6.1

然后重启ES就可以发现IK分词器被加载

使用kibana测试!

其中 ik_smart 为最少切分

   GET _analyze
{
  "analyzer":"ik_smart",
  "text":"我是马文博"
}

结果集:

   {
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "马文",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "博",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 3
    }
  ]
}

ik_max_word为最细粒度划分!穷尽词库的可能!字典!

GET _analyze
{
  "analyzer":"ik_max_word",
  "text":"今天是个好日子"
}

结果集

{
  "tokens" : [
    {
      "token" : "今天是",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "今天",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "是",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "CN_CHAR",
      "position" : 2
    },
    {
      "token" : "个",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "CN_CHAR",
      "position" : 3
    },
    {
      "token" : "好日子",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "日子",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 5
    }
  ]
}

为ik分词器添加自定义字典

1.在ES插件ik分词器下的config文件夹新建自定义dic
2.修改ES插件ik分词器下的config文件夹下的IKaAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">mydic.dic</entry>   
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

3.重启ES

猜你喜欢

转载自blog.csdn.net/qq_35416214/article/details/106264386