ElasticSearch 搜索引擎
ES简介
ElasticSearch作为一个基于Apache Lucene的实时分布式搜索和分析引擎,具有十分强大的功能:
- 全文搜索
- 实时搜索
- 分析与聚合
通过ES可以很方便的使大量数据具有搜索、分析和探索的能力。ES出色的性能也让其备受各类公司的喜爱,譬如WikiPedia,StackOverflow以及Github。
同时ElasticSearch和关系型数据库比如MySQL有很多相似的概念,因此上手门槛很低:
关系型数据库(比如MySQL) | 非关系型数据库(ElasticSearch) |
---|---|
数据库Database | 索引Index |
表Table | 类型Type |
数据行Row | 文档Document |
数据列Column | 字段Field |
约束Schema | 映射Maping |
创建——PUT
创建索引
- 设置分析器
分析器主要是将文本转换为tokens和terms,并以此创建用于搜索的倒排索引。分析器都由三种构件组成的:character filters , tokenizers 以及 token filters。
- character filter 字符过滤器,在一段文本进行分词之前,先进行预处理,比如说最常见的就是过滤html标签
- tokenizers 分词器,分割输入的文本。比较常用的有Standard Analyzer - 默认分词器,按词切分,小写处理;Simple Analyzer - 按照非字母切分(符号被过滤), 小写处理;Whitespace Analyzer - 按照空格切分,不转小写;中文的分词器比较推荐的是IK分词器,IK有两种颗粒度的拆分:ik_smart: 会做最粗粒度的拆分,ik_max_word: 会将文本做最细粒度的拆分
- token filters token过滤器,将切分的单词进行加工,比如大小写转换(例将“Quick”转为小写),去掉词(例如停用词像“a”、“and”、“the”等等)
下面的例子中,创建索引使用了自定义的分析器,分词器使用的是standard,并且还过滤了西班牙语中的停用词。
PUT /test_index
{
"settings": {
"analysis": {
"analyzer": {
"new_ana":{
"type":"standard",
"stopwords":"_spanish_"
}
}
}
},
"mappings": {
"properties": {
"first_name": {
"type": "keyword"
},
"last_name": {
"type": "keyword"
},
"age": {
"type": "integer"
},
}
}
}
POST /test_index/_analyze
{
"analyzer":"new_ana",
"text":"El veloz zorro marrón"
}
创建文档
// PUT /{index}/{type}/{id}
PUT /test_index/_doc/1
{
"first_name":"John",
"last_name":"Smith",
"age":26
}
PUT /test_index/_doc/2
{
"first_name":"Jane",
"last_name":"Smith",
"age":22
}
查看文档——GET
查看文档
//查看某文档
// GET /{index}/{type}/{id}
GET /test_index/_doc/1
查询表达式(Query DSL)
query下进行灵活查询
GET /_search
{
"query": YOUR_QUERY_HERE
}
参数 | 说明 |
---|---|
range | 限制结果范围range。常用的参数包括:gt大于,gte大于等于,lt小于,lte小于等于 |
term | 精确匹配数字、时间、布尔等,搜索的内容不会进行分词 |
match_all | 全部搜索 |
match | 模糊搜索,搜索的内容会进行分词 |
multi_match | 多次搜索,可以一次查询多个field |
match_phrase | 精确搜索,搜索的内容会进行分词,而且还有顺序的要求 |
bool | 合并搜索 |
具体例子:
// range:查找年龄大于25的文档
GET /test_index/_search
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gte": 25
}
}
}
}
}
}
// term:精确查找first_name是John的文档
GET /test_index/_search
{
"query": {
"term": {
"first_name": "John"
}
}
}
// multi_search:查找first_name和last_name为John的文档
GET /test_index/_search
{
"query": {
"multi_match" : {
"query": "John",
"fields": [ "first_name", "last_name" ]
}
}
}
// bool: 查找last_name为Smith的文档
GET /test_index/_search
{
"query": {
"bool": {
"must": {
"match": {
"last_name": "Smith"
}
}
}
}
}
// sort: 文档按age降序输出
GET /test_index/_search
{
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
// aggregate: 文档按age聚合
GET /test_index/_search
{
"aggs": {
"aggs_age": {
"terms": {
"field": "age"
}
}
}
}
删除——DELETE
delete某个文档不会导致文档真正地被删除,delete索引才是真正的删除
// 删除文档
// DELETE /{index}/{type}/{id}
DELETE /test_index/_doc/1
// 删除索引
DELETE /test_index