ElasticSearch 项目笔记

2018 年 10 月 18 日 • 阅读数: 122

ElasticSearch 项目笔记

概念简介

Elasticsearch是一个基于 Apache Lucene™ 的开源搜索引擎,但Lucene依赖于Java而且相当复杂

所以Elasticsearch的目的是通过简单的 RESTful API 来隐藏Lucene的复杂性,从而让全文搜索变得简单

不过,Elasticsearch不仅仅是Lucene和全文搜索,我们还能这样去描述它:

  • 分布式的实时文件存储,每个字段都被索引并可被搜索
  • 分布式的实时分析搜索引擎
  • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据

而且,所有的这些功能被集成到一个服务里面,应用可以通过简单的 RESTful API 、各种语言的客户端甚至命令行与之交互

基本名词解释

  • 集群:一个或多个节点组织在一起
  • 节点:一个节点是集群中的一个服务器,由一个名字来标识
  • 分片:将索引划分为多份的能力,允许水平分割和扩展容量,多个分片响应请求,提高性能和吞吐量
  • 副本:创建分片的一份或多份的能力,在一个节点失败其余节点可以顶上,提高系统的稳定性

类比数据库

elasticsearch mysql
index(索引) 数据库
type(类型)
documents(文档)
fields(字段)

倒排索引概念

Elasticsearch使用一种叫做 倒排索引(inverted index) 的结构来做快速的全文搜索

倒排索引由在文档中出现的唯一的单词列表,以及对于每个单词在文档中的位置组成

具体点说就是将一个文档进行分词,将得到的一个单独的词称作关键词并将其作为 key,将这个单词所属的文档列表(可能在多个文档中都要出现)作为 value 进行存储

同时它在 value 中,还会记录该关键词,在文档中出现的位置和词频

简单举例如下:

关键词 文档
python (doc1, <2, 10>, 2), (doc2, <6, 100>, 2)
java (doc2, <3, 4, 50>, 3)
php (doc5, <100, 110>, 2), (doc6, <1, 10, 50, 100>, 4)

映射(mapping)

创建索引的时候,可以预先定义字段的类型以及相关属性

Elasticsearch会根据JSON源数据的基础类型猜测你想要的字段映射,将输入的数据转变成可搜索的索引项

映射就是我们定义的字段的数据类型,同时告述Elasticsearch如何索引数据以及是否可以被搜索

作用:会让索引建立的更加细致和完善

类型:静态映射和动态类型

内置类型可分为

分类 类型
字符串类型 text,keyword
数字类型 long,integer,short,byte,double,float
日期类型 date
布尔类型 boolean
二进制类型 binary
复杂类型 object,nested
坐标类型 geo-point,geo-shape
专业类型 ip,competion

查询操作

查询分类:

  • 基本查询:使用elasticsearch内置的查询条件进行查询
  • 组合查询:把多个查询组合在一起进行复合查询
  • 过滤查询:查询同时,通过filter条件在不影响打分的情况下筛选数据

基本操作

插入操作

索引初始化操作 PUT {index_name}

PUT lagou
{
  "settings": {
    "index": {
      "number_of_shards": 5,
      "number_of_replicas": 1
    }
  }
}

保存文档 PUT {index_name}/{type_name}/{id}

自定义映射

PUT lagou
{
  "mappings": {
    "job":{
      "properties":{
        "title":{
          "store":true,
          "type":"text",
          "analyzer":"ik_max_word"
        },
        "company_name":{
          "store":true,
          "type":"keyword"
        },
        "desc":{
          "type":"text"
        }
      }
    }
  }
}

如果不指定文档ID,Elasticsearch也会生成默认ID的

PUT lagou/job/1
{
  "title": "python分布式爬虫",
  "salary_min": 15000,
  "city": "北京",
  "company": {
    "name": "百度",
    "company_addr": "北京软件园"
  },
  "publish_date": "2018-9-9",
  "comments": 15
}

:在Elasticsearch6.0以后的版本中一个index只能有一个type

删除操作

删除文档 DELETE {index_name}/{type_name}/{id}

DELETE lagou/job/1

删除索引 DELETE {index_name}

DELETE lagou

:无法直接删除type

修改操作

修改索引的设置 PUT {index_name}/_settings

PUT lagou/_settings
{
  "number_of_replicas": 2
}

修改文档,全部覆盖的方式 PUT {index_name}/{type_name}/{id}

PUT lagou/job/1
{
  "title": "python分布式爬虫",
  "salary_min": 20000,
  "city": "北京",
  "company": {
    "name": "百度",
    "company_addr": "北京软件园"
  },
  "publish_date": "2018-9-9",
  "comments": 15
}

:如果不传完整的数据,部分字段将丢失

修改文档,部分更新的方式 POST {index_name}/{type_name}/{id}/_update

POST lagou/job/1/_update
{
  "doc": {
    "comments": 20  
  }
}

:修改的字段需要放在"doc"中

获取操作

获取索引的值

GET lagou
GET lagou/_settings
GET _all/_settings
GET _settings
GET .kibana,lagou/_settings

获取文档数据

GET lagou/job/1
GET lagou/job/1?_source
GET lagou/job/1?_source=title
GET lagou/job/1?_source=title,city

查询操作

match查询

会进行分词

GET lagou/_search
{
  "query": {
    "match": {
      "title": "搜索"
    }
  }
}

term查询

会进行分词

GET lagou/_search
{
  "query": {
    "term": {
      "company_name":"百度"
    }
  }
}

terms查询

依此匹配

GET lagou/_search
{
  "query": {
    "terms": {
      "title": [
        "搜索",
        "爬虫"
      ]
    }
  }
}

match_all

返回所有

GET lagou/_search
{
  "query": {
    "match_all": {}
  }
}

match_phrase查询

短语搜索,分词之后,满足所有词才能返回结果

slop:两个词之间的最大距离,超过该距离也不能返回结果

GET lagou/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "python搜索",
        "slop": 2
      }
    }
  }
}

multi_match查询

可以指定多个字段

字段后面^3可以表示权重

GET lagou/_search
{
  "query": {
    "multi_match": {
      "query": "python",
      "fields": ["title^3", "desc"]
    }
  }
}

range查询

指定查询范围

get:大于等于,lte:小于等于;ge:大于,lt:小于

boost:权重

特别的时间类型的值可以直接使用now表示当前

GET lagou/_search
{
  "query": {
    "range": {
      "comments": {
        "gt": 10,
        "lt": 20,
        "boost": 1
      }
    }
  }
}

wildcard

简单的模糊查询

*表示统配符

GET lagou/_search
{
  "query": {
    "wildcard": {
      "title": {
        "value": "py*n",
        "boost": 2
      }
    }
  }
}

控制查询返回的数量

from:开始的位置

size:返回的数量

GET lagou/_search
{
  "query": {
    "match": {
      "title": "python"
    }
  },
  "from": 0,
  "size": 2
}

指定返回的字端

只能指定store未true的

GET lagou/_search
{
  "stored_fields": ["title", "company_name"],
  "query": {
    "match": {
      "desc": "数据结构"
    }
  }
}

结果排序

desc从大到小,asc相反

GET lagou/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "comments": {
        "order": "asc"
      }
    }
  ]
}

bool查询

# 组合查询
# bool查询包括 must should must_not filter
# 格式如下
# bool:{
#   "filter":[],  字段过滤
#   "must":[],    必须全部满足
#   "should":[],  满足任意一个都可以
#   "must_not":[] 不能满足任意一个
# }
# bool 里面也可以使用bool,做到嵌套查询

GET lagou/_search
{
  "query": {
    "bool": {
      "must": [
        {"match_all": {}},
        {"match": {
          "title": "scrapy"
        }}
      ],
      "filter": {
        "term": {
          "comments": 15
        }
      }
    }
  }
}

处理为空的字段

exists含有指定字段

GET lagou/_search
{
  "query": {
    "bool": {
      "filter": {
        "exists": {
          "field": "title"
        }
      }
    }
  }
}

查看分析器分析结果

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "python机器学习研发工程师"
}

GET _analyze
{
  "analyzer": "ik_smart",
  "text": "python机器学习研发工程师"
}
标签: ElasticSearch搜索引擎

召唤伊斯特瓦尔