最近项目要使用elasticsearch。。。这里总结一下看elasticsearch文档的一些总结吧。
基本概念
elasticsearch是一个全文本搜索的服务,比如github从几百亿行代码中搜索某个代码就用了elasticsearch。在mac下可以通过brew安装和管理,注意还要再安装一个kibana来进行可视化和管理(可以在kibana的console跑各种请求)。es默认跑在9200,kibana默认跑在5601端口。
这里注意对于中文场景要安装elasticsearch-analysis-ik进行分词,ik还支持自定义词典,可以在es-path/config/analysis-ik/custom下自定义dic。
概念对应关系如下表
传统数据库 | ElasticSearch |
---|---|
Database | Index |
Table | Type |
Row | Document |
Column | Field |
schema | mapping |
elasticsearch的所有内容都是通过json格式传递的。每个文档都是一个json的形式。一般文档包括下面三个metadata:
- _index:文档存储的地方(类似于database)
- _type:文档代表的对象的类(类似于table)
- _id:文档的唯一标示(类似于主见,可以自定义,也可以让es帮你生成)
es是支持分布式的,当然也有对应的shard和replica机制。
单机操作api
创建:
1 | PUT /{index}/{type}/{id} |
获取:
1 | GET /{index}/{type}/{id}?_source=title,text#可以获取特定字段(包含metadata) |
存在:
1 | HEAD /{index}/{type}/{id}#判断document是不是存在,只返回状态码而没有具体数据 |
更新:
由于elasticsearch中的文档是不可变的,所以修改只能通过重建或者脚本的方式更新
1 | PUT /{index}/{type}/{id} |
脚本的方式:
1 | POST {index}/{type}/{id}/_update#注意最后是一个_update |
删除:
1 | DELETE /{index}/{type}/{id}#删除某个文档 |
搜索:
elasticsearch最重要的功能就是搜索,搜索的姿势也是很多的
1 | GET /_search#在所有索引类型中搜索 |
对于搜索的结果,可以用size分页,用from决定从哪里出发
当然平时比较多的是查找字符串
1 | GET /_all/{type}/_search?q=tweet:elasticsearch#查找某个type中tweet:elasticsearch的文档 |
第二个要重点解释一下,其实在url encode之前为:
+describtion:max
如果要放在查询中,就要进行urlencode(percent encode),然后放在q后,即:
q=%2bdescribtion%3amax
这里的查询不仅限于字符串查找,还可以是特定条件下的查找,如
name
字段包含"mary"
或"john"
date
晚于2014-09-10
_all
字段包含"aggregations"
或"geo"
这个可以用
1 | +name:(mary john) +date:>2014-09-10 +(aggregations geo) |
来表示,最后urlencode即可进行查询。
mapping和Analysis
es的mapping对应了传统数据库的schema,其中es会对不同的字段类型进行猜测,得到对应的mapping,在这种情况下,对某个field的类型猜测可能会是date,但如果用_all搜索这个field则认为他是string,从而带来搜索结果的不同。
对于一个搜索引擎,与数据库最本质的区别在于确切值和全文文本之间。
传统数据库需要在where语句里的特定匹配,但es则希望如下:
- 一个针对
"UK"
的查询将返回涉及"United Kingdom"
的文档 - 一个针对
"jump"
的查询同时能够匹配"jumped"
,"jumps"
,"jumping"
甚至`”leap”
等等等场景,为此引出了es最关键的技术——倒排索引。
Analysis
对于大小写或者同源词等原本是不能匹配的,需要通过特定的分析过程才能被检索,具体过程如下:
- 首先,标记化一个文本快为适用于倒排索引的term
- 标准化这些term为标准行事,提高可搜索率和查全率
一个完成的分析器(analyzer)包括三部分:
- 字符过滤器:去掉一些html标签,或者转化&为and等
- 分词器:通过空格或逗号分词(中文需要特定分词工具ik)
- 标记过滤:将词进行大小写转换、去掉一些停用词(a、the这些)或者增加词(同义词)
可以通过如下方式测试analyzer
1 | GET _analyze?pretty |
如果想使用某个特定analyzer,而不是系统自带的standard,就需要通过mapping。
查看map需要用:
1 | GET /{index}/_mapping/{type} |
这样得到mappings的内容,注意现在一些field的类型是keyword(而不是text)是因为keyword不会自动分词并建立索引,但text会这么做。
1 | PUT final |