全文搜索引擎 Elasticsearch
写在前面
最近在学Elasticsearch ,
我相信只要是接触过开发的都会听过Elasticsearch或ELK这么一个技术。
主要用来做全文检索或大数据分析等,之前一直处理了解状态。
所以打算系统学学Elasticsearch ,这也算是我从零学习Elasticsearch的笔记吧。
1. Elasticsearch 术语介绍
1.1 文档Document
- 用户存储在es中的数据文档
- es存储数据的最小单元
- 类比于数据库一行数据
1.2 索引Index
-由相同字段的文档列表组成
- 类比于数据库中的表
ps: es6.0版本之前,索引下面可以新建多个Type,就把这个Index类比于database,
但是在,6.0版本之后,一个索引下面只能够新建一个Type ,所以类比于表更合适
1.3 节点Node
- 一个ES的运行实例,是集群的基本单元
1.4 集群Cluser
- 有一个或多个节点组成,对外提供服务
2.Document 介绍
Document 主要就是一个Json Object
json对象有一些字段(Field)组成,常见数据类型:
- 字符串 :text , keywork
- 数值型 :long , integer , byte ,double , float , half_float(节省空间) , scaled_float(节省空间)
- 布尔: boolean
- 日期:date
- 二进制 : binary
- 范围类型 (新的类型): integer_range , float_range , long_tange , double_range, date_range
注意:每一个文档Document都有一个唯一的ID标识
- 可以自行指定
- es 自动生成
示例Document
{
"remote_ip":"123.207.226.36",
"user_name":"liuge",
"@timestamp":"2015-05-14T08:23:52.000Z",
"request_action":"GET",
"http_version":"1.1",
"response":"304",
"bytes":"0",
"referrer":"-",
"agent":"-"
}
每一个Document都有一个MetaData (元数据)
元数据:用于标注文档的相关信息
- _index:文档所在的索引名
- _type: 文档所在的类型名
- _id:文档的唯一ID
- _ uid:组合id,由_type和_id组成(6.X版本_type不再起作用)
- _source:文档的原始Json数据,可以从这里获取每一个字段的内容
- _all:整合所有字段的内容到该字段,默认禁用,不推荐
3.Index (索引) 介绍
类比于table,具有相同结构文档的集合
- 每个索引都有自己的 mapping 定义 , 用于定义字段名和类型
一个集群可以有多个索引
3.RESTful API 介绍
es集群对外提供RESTful API:用户操作集群中的数据
- 表现层 状态 转移
- URI 指定资源 ,如:Index ,Document
- Http Method 指明资源操作类型,如:GET,POST,PUT,DELETE等
与es集群资源进行交互的方式:
方式一:Curl命令行
curl -XPUT "HTTP://localhost:9200/ceshi/doc/1" -i -H "Content-Type:application/json" -d
'
{
"username":"liuge",
"job":"软件开发"
}
'
方式二:Kibana DevTools
PUT /ceshi/doc/1
{
"useranme":"liuge",
"job":"软件开发"
}
4.Mapping 介绍
Mapping设置,即如何定义数据字段和类型
==========Mapping的字段类型(Filed type)===========================
核心数据类型:
- 字符串 :text (会分词), keywork(不会分词)
- 数值型 :long , integer , byte ,double , float , half_float(节省空间) , scaled_float(节省空间)
- 布尔: boolean
- 日期:date
- 二进制 : binary
- 范围类型 (新的类型): integer_range , float_range , long_tange , double_range, date_range
复杂的数据类型:
- 数组类型 array
- Object
- 嵌套类型 nested object
地理位置数据类型:
- geo_point
- geo_shape
专用类型:
- 记录ip地址
- 实现自动补全completion
- 记录分次数 token_count
- 记录字符串 hash
- percolator
多字段特性:
- 允许对同一个字段采用不同的配置,比如分词,常见的实现汉字实现拼音搜索
- 实现方式:在汉字中新增一个子字段为pinyin就可以
Kibana DevTools方式:(推荐)
4.1 自定义一个mapping
PUT accounts
{
"settings": {
"index": {
"number_of_shards" : 1,
"number_of_replicas" : 0
}
},
"mappings":{
"doc":{
"dynamic":false, # 设置不允许动态添加,结果是,可以插入未定义的字段,但是不能通过未定义字段值来进行查询
"properties":{
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}
上面代码中,首先新建一个名称为accounts的 Index
这三个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。
Elastic 的分词器称为 analyzer。我们对每个字段指定分词器。
"user": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。
4.2 新增记录,带上id
PUT accounts/doc/1
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
新增记录的时候,也可以不指定 Id,这时要改成 POST 请求
POST accounts/doc
{
"user": "李四",
"title": "工程师",
"desc": "系统管理"
}
4.3 删除数据
DELETE accounts/doc/1
DELETE accounts
4.4更新记录就是使用 PUT 请求,重新发送一次数据。
PUT accounts/doc/1
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理,软件开发"
}
4.3 查询数据
使用 GET 方法,直接请求/Index/Type/_search,就会返回所有记录
GET accounts/doc/_search
/Index/Type/id ,返回指定id的记录
GET accounts/doc/1
GET accounts/doc/_search
{
"query":{
"term":{
"_id":"1"
}
}
}
GET accounts/doc/_search
{
"query" : {
"match" : {
"desc" : "管理"
}
},
"from": 1,
"size": 1
}
上面代码使用 Match 查询,指定的匹配条件是desc字段里面包含"软件"这个词
Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。
还可以通过from字段,指定位移。
上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。
逻辑运算or
GET accounts/doc/_search
{
"query" : { "match" : { "desc" : "软件 系统" }}
}
逻辑运算and
GET accounts/doc/_search
{
"query": {
"bool": {
"must": [
{ "match": { "desc": "软件" } },
{ "match": { "desc": "系统" } }
]
}
}
}
5 分词介绍
5.1 Analysis
分词是指将文本转为一系列单词的过程,也叫作文本分析
在es里面称为Analysis
在es中专门负责分词的组件叫做分词器(Analyzer)
分词器(Analyzer),es会自带一部分词器
- Character Filters
- 针对原始的文本进行处理,例如,去除html,a,p,div特殊符号等
- Tokenizer
- 将原始的文本按照一定的规则切分为单词
- Token Filters
- 把Tokenizer再加工,大小写转换等,没有实际意义的词可以去掉,新增近义词,同义词等
ps:分词执行的顺序也是从上到下的
5.2 分词API的使用
Analyze(分词) API 使用
es提供的用于测试分词的api接口,验证分词效果
- 可以直接指定分词器(Analyzer)进行测试
POST _analyze
{
"analyzer":"standard", #这个测试用的standard分词器是es自己带的
"text":"Hello World!"
}
- 可以直接指定索引中的字段进行测试
POST test_index/_analyze
{
"field":"username", # 指定索引(表)的字段
"text":"hello world!"
}
- 可以自定义分析器进行测试
POST _analyze
{
"analyzer":"standard", #指明自己使用哪一个分词器
"filter":["lowercase"], #指明filter处理为小写
"text":"HEllo WOrld!"
}
5.3 预定义分词器
es中自带的分词器
如下:分词器前面讲到,就是由三个部分组成,这里自带的不同也是三个部分组成上不同
- standard Analyzer
- 默认分词器,按照单词的边界切分
- Tokenizer 1.standard
- Token Filters : 1.standard 2.Loswer case 3.Stop(默认禁用)
- Simple Analyzer
- 切分规则。按照非字母切分,非字母的部分会被删除
- Filters 1.Loswer case
- Whitespace Analyzer
- 按照空格进行切分
- Stop Analyzer
- 语气助词等修饰性词语会被移除,比如,the ,an ,的,这那等
- 相比于Simple Analyzer 多了修饰性词语的移除
- Filters 1.Loswer case 2.stop
- Keyword Analyzer
- 不进行分词操作
- 原样输出,当你不想对文本做分词操作的时候
- Pattern Analyzer
- 自定义切分的规则,正则匹配
- 默认是 \W+ ,即非字词的符号作为分隔符,空格 ~ = ‘ 等特殊符号
- Language Analyzer
- 提供了30+ 常见语言的分词器
中文分词:是指将一句中文句子切分为一个个单独的词
在英文中,句子内单词可以使用空格做明显分隔,
在中文中,句子内的词语是没有分隔的
常见中文分词系统:
- IK
- jieba
高阶一点的:基于自然语言处理的分词系统
- Hanlp
- THULAC
5.4 自定义分词器
当自带的分词器无法满足需求的时候,可以自定义分词
通过自定义分词的三个部分来实现:
- Character Filters
- Tokenizer
- Token Filters
5.4.1 Character Filters
- 针对原始的文本进行处理,例如,去除html,a,p,div特殊符号等
自带的如下:
- HTML Script 去除html 标签和转换html实体
- Mapping 进行字符串的替换操作
- Pattern Replace进行正则匹配替换
会影响到Tokenizer解析position和offset
5.4.2 Tokenizer
-将原始文本按照一定规则切分为单词
自带的如下:
- standard按照单词进行分割
- latter 按照非字符类进行分割
- whitespace 按照空格进行分割
- UAX URL Email 按照standard 分割 ,但不会分割邮箱和URL
- NGram 和Edge NGram 连词分割
- Path Hierachy 按照文件路径进行分割
测试:
POST _analyze{
"tokenizer":"path_hierachy",
"text":"/one/two/three"
}
5.4.3 Token Filters
- 将tokenizer 输出的单词(term )进行增加,删除,修改等操作
自带的如下:
- lowercase 将所有输出的单词转换为小写
- stop 删除 stop words
- NGram 和 Edge Ngram 连词分割
- Synonym 添加近义词的term
重要,这里可以实现自动补全的功能
POST _analyze{
"text":"a Hello World!",
"tokenizer":"standard",
"filter":[
"stop", # 当有多个filter的时候,会依次执行
"lowercase",
{
"type":"ngram",
"min_gram":2,
"max_gram":4
}
]
}
5.5 自定义分词的API
自定义分词器在索引(具体表)中的设定:
PUT test_index{
"settings":{
"analysis":{
"char_filter":{},
"tokenizer":{},
"filter":{},
"analyzer":{}
}
}
}
demo
PUT testairbnb
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"analyzer": {
"autosuggest_analyzer": {
"filter": [
"lowercase",
"asciifolding",
"autosuggest_filter"
],
"tokenizer": "standard",
"type": "custom"
},
"ngram_analyzer": {
"filter": [
"lowercase",
"asciifolding",
"ngram_filter"
],
"tokenizer": "standard",
"type": "custom"
}
},
"filter": {
"autosuggest_filter": {
"max_gram": "20",
"min_gram": "1",
"token_chars": [
"letter",
"digit",
"punctuation",
"symbol"
],
"type": "edge_ngram"
},
"ngram_filter": {
"max_gram": "9",
"min_gram": "2",
"token_chars": [
"letter",
"digit",
"punctuation",
"symbol"
],
"type": "ngram"
}
}
}
}
},
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"accommodates": {
"type": "integer"
},
"bathrooms": {
"type": "integer"
},
"bed_type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"bedrooms": {
"type": "integer"
},
"beds": {
"type": "integer"
},
"date_from": {
"type": "date",
"format": "yyyyMMdd"
},
"date_to": {
"type": "date",
"format": "yyyyMMdd"
},
"has_availability": {
"type": "boolean"
},
"host_image": {
"type": "keyword",
"ignore_above": 256,
"index": false
},
"host_name": {
"type": "text",
"analyzer": "autosuggest_analyzer",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"image": {
"type": "keyword",
"ignore_above": 256,
"index":false
},
"listing_url": {
"type": "keyword",
"ignore_above": 256
},
"location": {
"type": "geo_point"
},
"name": {
"type": "text",
"analyzer": "autosuggest_analyzer",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"price": {
"type": "float"
},
"property_type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"room_type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
上面分词的配置中,能够完全实现个性化设定
参考文章http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
参考文章https://coding.imooc.com/class/chapter/181.html
全文搜索引擎 Elasticsearch的更多相关文章
- 全文搜索引擎Elasticsearch入门实践
全文搜索引擎Elasticsearch入门实践 感谢阮一峰的网络日志全文搜索引擎 Elasticsearch 入门教程 安装 首先需要依赖Java环境.Elasticsearch官网https://w ...
- Spring Boot 全文搜索引擎 ElasticSearch
参考 全文搜索引擎ElasticSearch 还是Solr? - JaJian - 博客园
- 全文搜索引擎 Elasticsearch 入门
1. 百科 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作 ...
- 3.高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建
高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建 如果大家看了我的上一篇<2.高并发教程-基础篇-之nginx+mysql实现负载均衡和读写分离>文章,如果能很好的 ...
- 全文搜索引擎 Elasticsearch 安装
全文搜索引擎 Elasticsearch 安装 学习了:http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html 拼音:https://www ...
- 全文搜索引擎 ElasticSearch 还是 Solr?
最近项目组安排了一个任务,项目中用到了全文搜索,基于全文搜索 Solr,但是该 Solr 搜索云项目不稳定,经常查询不出来数据,需要手动全量同步,而且是其他团队在维护,依赖性太强,导致 Solr 服务 ...
- 全文搜索引擎 Elasticsearch 入门教程
全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选. 它可以快速地储存.搜索和分析海量数据.维基百科.Stack Overflow.Gi ...
- 分布式全文搜索引擎ElasticSearch
一 什么是 ElasticSearch Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elas ...
- 全文搜索引擎 Elasticsearch 介绍
全文搜索属于最常见的需求,开源的 Elasticsearch (以下简称 Elastic)是目前全文搜索引擎的首选. 它可以快速地储存.搜索和分析海量数据.维基百科.Stack Overflow.Gi ...
- 全文搜索引擎Elasticsearch详细介绍
我们生活中的数据总体分为两种:结构化数据 和 非结构化数据. 结构化数据:也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理.指具有固 ...
随机推荐
- 一文搞懂Python中的所有数组数据类型
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...
- Codeforces 1009D
题意略. 思路: 可知对于一个拥有n个点的图来说,它至少需要有n - 1条边来维持连通性,而且数字1恰好与后面的n - 1个数字互质: 至于n个点的图可以产生合法的互质边的个数的上限,我们可以通过莫比 ...
- P2762 太空飞行计划问题 最大权闭合子图
link:https://www.luogu.org/problemnew/show/P2762 题意 承担实验赚钱,但是要花去对应仪器的费用,仪器可能共用.求最大的收益和对应的选择方案. 思路 这道 ...
- codeforce375div2-D. Lakes in Berland 搜索
Lakes in Berland 题意与解释:这道题就是求图中被围起来的点群,问最少去掉几个点,可以使得孤立的点群数目为K; 因为自己写的代码又长又had bugs. 我自己写的bfs,想着是先染色, ...
- ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
- Codeforces 374 C Inna and Dima (DFS)
Inna and Dima 题意:从图上的任意一个D点按着DIMADIMA的顺序走,问一共可以经过多少个DIMA,如果经过0个DIMA就输出“Pool DIma!“,如果可以有无数多个DIMA就输出” ...
- codeforces 794 C. Naming Company(贪心)
题目链接:http://codeforces.com/contest/794/problem/C 题意:有两个人每个人都有一个长度为n的字符串,两人轮流拿出一个字符串,放在一个长度为n的字符串的指定位 ...
- @PathVariable性能损耗分析
前端时间参与了一次业务线排障,是接口服务并发性能比较差,性能损耗大的问题,我经过几次研究分析和压测,确定了故障源是@PathVariable耗时过长引起的. @PathVariable使用形式: @R ...
- JS-特效 ~ 03. 楼层跳跃、事件对象event的获取与使用、event的主要内容、screenX、pageX、clientX的区别、放大镜、模拟滚动条
楼层跳跃 100%子盒子会继承父盒子的宽高.父盒子继承body宽高.Body继承html的宽高. 盒子属性:auto:适应盒子自身的宽度或者高度.(对自己负责) 盒子属性:100%:适应盒子父盒子的宽 ...
- 封装axios来管控api的2种方式
前言:我们在开发项目的时候,往往要处理大量的接口.并且在测试环境 开发环境 生产环境使用的接口baseurl都不一样 这时候如果在开发环境完成之后切换每一个接口的baseurl会变的非常的麻烦,(要去 ...