ElasticSearch是一个基于Lucene的分布式多用户全文搜索引擎,使用Json索引,提供RESTful API,有着极高的实时搜索性能。html
ES主要功能git
优势github
ES特性算法
索引结构sql
健康状态docker
Mysql : ES 关系对比数据库
在具体存储空间选型时须要考虑一下几点:json
存储空间选型建议:
通常一种文档数据即占用一个INDEX空间,除非知足如下条件可考虑TYPE空间数组
DockerFile:缓存
FROM elasticsearch:2.3.5 # head插件 RUN /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head # IK分词安装 RUN mkdir /usr/share/elasticsearch/plugins/analysis-ik \ && cd /usr/share/elasticsearch/plugins/analysis-ik \ && wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v1.9.5/elasticsearch-analysis-ik-1.9.5.zip \ && unzip elasticsearch-analysis-ik-1.9.5.zip \ && rm -fr elasticsearch-analysis-ik-1.9.5.zip
镜像构建与启动:
docker build -t test/elasticsearch . docker run -d -p 9200:9200 -p 9300:9300 --name=es test/elasticsearch # 检查插件(应该会罗列head、 analysis-ik两个插件) docker exec es bin/elasticsearch-plugin list
访问:
http://localhost:9200
http://192.168.137.4:9200/_plugin/head
analyzer
分析器由如下组成:
char_filter
字符过滤器tokenizer
分词器filter
词条过滤器IK分词:
plugins/analysis-ik/config/custom/mydict.dic
文件中追加自定义词条plugins/analysis-ik/config/IKAnalyzer.cfg.xml
中配置utf-8远程词库remote_ext_dict地址Last-Modified、ETag
,任一值变更都会触发IK插件进行词库热更新WebServer
在 client
请求文件的内容发生变动时 会自动更新Last-Modified、ETag
两个头部信息测试分词器
curl -XGET 'http://localhost:9200/索引/_analyze?analyzer=ik&pretty=true&text=xxx'
curl -XPUT http://localhost:9200/索引
curl -XPUT http://localhost:9200/索引/_mapping/类型 -d' { "properties": { "字段": { "type": "text", #byte、integer、float、string、date、boolean、geo_point、geo_shape、nested(用于嵌套的对象数组)、object(用于对象,对象会被扁平化处理) "index": "analyzed", #analyzed(全文搜索)、not_analyzed(精确值搜索)、no(不可搜索); "analyzer": "ik_max_word", "include_in_all": true, #该字段是否要包含在_all字段中进行搜索 "fields": { "子字段1": { "type": "string" } } } } } #子字段查询标识 字段.子字段1 # 默认索引模式 - string类型默认`analyzed` - 其余简单类型默认`not_analyzed`
curl -XPUT http://localhost:9200/索引/类型/id -d'xxx'
curl -XPOST http://localhost:9200/索引/类型 -d'xxx'
curl -XPUT http://localhost:9200/索引/类型/id -d'xxx'
curl -XDELETE http://localhost:9200/索引
curl -XGET http://localhost:9200/索引/类型/id
curl -XGET http://localhost:9200/索引/类型/_search?查询字符串
查询字符串:
q=xxx:yyy
+
追加匹配条件,-
追加不匹配条件sort=字段:desc|asc
DSL请求体形式 curl -XPOST http://localhost:9200/_search -d'DSL请求体'
(注意请求类型是post)
DSL请求体
{}
{query:查询表达式, sort:排序, from:起始数, size:每页文档数}
查询模式
查询表达式
{查询方法: 值}
{查询方法: {字段:值}}
{ bool:{ 合并关系: 查询语句 或 [查询语句], ... } }
查询语句合并关系
每一个子查询有本身的评分,在bool时合并评分,如下每一个合并关系在每一个bool的直接下级中只能调用一次
常见查询语句
{match_all: {}}
{match: {字段: 值}}
{multi_match: {query:值, fields:[字段1, ...]}}
{range: {字段:{gte:最小值,lt:最大值}}}
{term: {字段:值}}
{terms: {字段:[值1,...]}}
{exists: {field:字段}}
{nested: {path:上级字段, query:查询表达式}}
注意
{ "term" : { "tags" : "search" } }
能够匹配字段 { "tags" : ["search", "open_source"] }
查询调试
curl -XGET http://localhost:9200/索引/类型/_validate/query -d{}
curl -XGET http://localhost:9200/索引/类型/_validate/query?explain -d{}
curl -XGET http://localhost:9200/_search?explain&format=yaml -d{}
curl -XGET http://localhost:9200/索引/类型/ID/_explain -d{}
默认相关性得分降序排列 curl -XGET http://localhost:9200/索引/类型/_search -d'{query:查询表达式, sort:排序, from:起始数, size:每页文档数}'
查询结果集排序:
{字段: {order:desc|asc}}
{字段: {order:desc|asc, mode:归一模式}}
min、max、avg、sum、
index:analyzed
的String
会被ES处理成多值字段[{字段1: {order:desc|asc}}, ...]
注意:
index:not_analyzed
字段上进行排序index:analyzed
字段上排序极耗内存请求结构 curl -XGET http://localhost:9200/索引/类型/_search -d'{query:查询表达式, highlight:高亮表达式}'
高亮表达式:
{ pre_tags : [<tag1>], post_tags : [</tag1>], fields : { _all: { pre_tags : [<tag1>], post_tags : [</tag1>], fragment_size: 100, #匹配片断长度 number_of_fragments: 5, #匹配片断数 no_match_size: 0, #无匹配状况下文本长度 } field1 : {} } }
请求体
curl -XGET http://localhost:9200/索引/类型/_search -d { size:0, #设置查询结果集数目为0提升聚合查询速度 query:查询表达式, aggs:聚合表达式, }
聚合表达式
{ 聚合名1:{ 聚合方法:{field:字段} global:{}, #声明在全局桶下聚合(聚合运算基于所有文档) aggs:嵌套聚合表达式(仅桶类聚合下面能够增长嵌套聚合) }, ... }
聚合构成
一个聚合的每一个 层级 均可以有多个度量或桶
聚合方法
分桶聚合通用参数
距离算法distance_type
圈过滤
{ geo_distance:{ distance:1km, distance_type:距离算法, location位置字段:{ lon:对比经度 lat:对比纬度 } } }
环过滤
{ geo_distance_range:{ gte:1km,内径 lte:1km,外径 distance_type:距离算法, location位置字段:{ lon:对比经度 lat:对比纬度 } } }
排序
{ _geo_distance:{ location位置字段:{ lat:对比纬度, lon:对比经度 }, nested_path:可选的nest路径, order:desc|asc, unit:km, distance_type:距离算法 } }
返回结果中,每一个条目的sort字段首个值即为相对距离/m
{ index: my_index, body: { query: { bool: { must: [ #评分模式的搜搜匹配 {match: {字段: 值}}, ... {nested: { path:上级字段, query: { bool: { must: [ {match: {上级字段.该级字段: 值}}, ... ] } } }} ], filter: [ #不评分模式的过滤 {term: {字段:值}}, {range: {字段:{gte:最小值,lt:最大值}}}, ... { geo_distance:{ distance:1km, distance_type:距离算法, location位置字段:{ lon:对比经度 lat:对比纬度 } } } ], } }, from: 100, size: 50, sort: [ {排序字段: {order: desc}}, ... {_geo_distance:{ location位置字段{ lon:对比经度 lat:对比纬度 }, order:asc, unit:km, distance_type:距离算法 } } ], highlight: { { fields : { myField: { pre_tags : [<tag1>], post_tags : [</tag1>], fragment_size: 100, #匹配片断长度 number_of_fragments: 5, #匹配片断数 no_match_size: 0, #无匹配状况下文本长度 } } } }, aggs: { 聚合名: { term: {field: 字段名}, ... aggs: { mySum: {sum: {field:字段名}} } }, ... }, } }