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