博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
全文搜索引擎 ElasticSearch
阅读量:6970 次
发布时间:2019-06-27

本文共 9359 字,大约阅读时间需要 31 分钟。

hot3.png

ElasticSearch是一个基于Lucene的分布式多用户全文搜索引擎,使用Json索引,提供RESTful API,有着极高的实时搜索性能。

基础知识

ES主要功能

  • 全文搜索引擎(倒排索引:根据词找到 位置&频次)
  • 数据分析系统(尤其是时间序列数据的聚合分析)
  • 分布式实时存储系统

优点

  • 高效的分词搜索
  • 强大的聚合运算

ES特性

  • 集群由主节点(负责管理集群所有变更)和普通节点组成
  • 索引被切割为分片调配到集群节点上(分片上并存着原始文档),主分片数在索引创建时即已确定
  • 副本分片用于实现故障切换,负载均衡(分片的备份套数随时可变)

索引结构

  • 分片、副本等配置
  • Type Mapping配置,包含:
    • 元数据配置
    • 字段域的类型、索引及搜索方式

健康状态

  • 绿色:所有主副分片均正常
  • 黄色:副本分片存在不正常
  • 红色:主分片有存在不正常

Mysql概念对比

Mysql : ES 关系对比

  • 数据库 : 索引 index
  • 表 : 类型 type
  • 行 : 文档 document
  • 列 : 字段 field
  • Schema : 映射 mapping
  • SQL : DSL

Index VS Type

在具体存储空间选型时需要考虑一下几点:

  • Index由一系列分片组成, 每个分片即一个Lucene索引实例并存在磁盘,内存,文件句柄的开销
  • 查询结果时,ES需要合并所有相关Index下的所有分片的结果集
  • 同Index下的不同Type有资源争用问题
  • 相关性得分在Index范围内计算, 不同类型Type会相互影响判分

存储空间选型建议:

一般一种文档数据即占用一个INDEX空间,除非满足以下条件可考虑TYPE空间

  • 两种文档有明显父子关系
  • 两种文档有类似的mapping结构
  • 每个Type下的文档量级不是特别大

基于Docker安装

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

镜像构建与启动:

  • API服务端口:9200
  • 集群节点通信端口:9300
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

访问:

  • API接口:http://localhost:9200
  • head插件:http://192.168.137.4:9200/_plugin/head

中文分词

analyzer分析器由以下组成:

  • char_filter字符过滤器
  • tokenizer分词器
  • filter词条过滤器

IK分词:

  • 支持自定义本地词库
    • plugins/analysis-ik/config/custom/mydict.dic文件中追加自定义词条
    • 重启ES服务
    • 重建相关数据的索引
  • 支持热更新远程词库
    • plugins/analysis-ik/config/IKAnalyzer.cfg.xml中配置utf-8远程词库remote_ext_dict地址
    • 词库地址http头部需返回Last-Modified、ETag,任一值变动都会触发IK插件进行词库热更新
    • 常规WebServerclient请求文件的内容发生变更时 会自动更新Last-Modified、ETag两个头部信息
  • 可用分词器
    • ik_smart: 会做最粗粒度的拆分
    • ik_max_word: 会将文本做最细粒度的拆分

测试分词器

curl -XGET 'http://localhost:9200/索引/_analyze?analyzer=ik&pretty=true&text=xxx'

索引管理

  • 初始化Index curl -XPUT http://localhost:9200/索引
  • 创建Type Mapping
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`
  • Index文档
    • 指定id curl -XPUT http://localhost:9200/索引/类型/id -d'xxx'
    • 自动id curl -XPOST http://localhost:9200/索引/类型 -d'xxx'
  • Index更新 curl -XPUT http://localhost:9200/索引/类型/id -d'xxx'
  • Index删除 curl -XDELETE http://localhost:9200/索引
  • 检索文档 curl -XGET http://localhost:9200/索引/类型/id

基本查询

curl -XGET http://localhost:9200/索引/类型/_search?查询字符串

查询字符串:

  • q匹配参数q=xxx:yyy
    • 如果q参数没有指定字段,则查询 _all 字段(所有字段值拼接成的大字符串)
    • +追加匹配条件,-追加不匹配条件
  • sort排序参数 sort=字段:desc|asc
    • sort可指定多次

复合查询

DSL请求体形式 curl -XPOST http://localhost:9200/_search -d'DSL请求体' (注意请求类型是post)

DSL请求体

  • 空查询 {}
  • DSL查询表达式 {query:查询表达式, sort:排序, from:起始数, size:每页文档数}

查询模式

  • filters过滤模式:高效 不评分查询(结果缓存)
  • queries搜索模式:低效 评分查询(结果不缓存) 一般query前先filter来缩减查询规模

查询表达式

  • 单一查询语句
    • 不指定字段 {查询方法: 值}
    • 指定了字段 {查询方法: {字段:值}}
  • bool合并查询语句
{	    bool:{		    合并关系: 查询语句 或 [查询语句],		    ...	    }	}

查询语句合并关系

每个子查询有自己的评分,在bool时合并评分,以下每个合并关系每个bool的直接下级中只能调用一次

  • filter 必须匹配(不评分模式的过滤)
  • must 必须匹配(评分模式的搜索)
  • must_not 必须不匹配
  • should 希望匹配(匹配其一则加分,用于修正相关性)
  • minimum_should_match 指定should方式的最小匹配次数
    bool查询若只有filter则可替换为constant_score查询,从而使评分为常量值

常见查询语句

  • match_all 匹配所有文档(默认查询方法){match_all: {}}
  • match 标准查询(字段配置决定全文或精确查询){match: {字段: 值}}
  • multi_match 多字段匹配 {multi_match: {query:值, fields:[字段1, ...]}}
  • range 区间查询 {range: {字段:{gte:最小值,lt:最大值}}}
  • term 精确值查询 {term: {字段:值}}
  • terms 多值精确查询(等于其一就行){terms: {字段:[值1,...]}}
  • exists、missing 字段有值判断 {exists: {field:字段}}
  • nested 嵌套查询 {nested: {path:上级字段, query:查询表达式}}

注意

  • term 和 terms 是 包含(contains) 操作,而非 等值(equals),即 { "term" : { "tags" : "search" } } 可以匹配字段 { "tags" : ["search", "open_source"] }
  • 参考 finding_multiple_exact_values.html#%E5%8C%85%E5%90%AB_%E8%80%8C%E4%B8%8D%E6%98%AF%E7%9B%B8%E7%AD%89

查询调试

  • 校验语法: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:analyzedString会被ES处理成多值字段
  • 多字段排序 [{字段1: {order:desc|asc}}, ...]

注意:

  • 尽量在index:not_analyzed字段上进行排序
  • 然而在index:analyzed字段上排序极耗内存

查询高亮

请求结构 curl -XGET http://localhost:9200/索引/类型/_search -d'{query:查询表达式, highlight:高亮表达式}'

高亮表达式:

{    pre_tags : [
], post_tags : [
], fields : { _all: { pre_tags : [
], post_tags : [
], 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:嵌套聚合表达式(仅桶类聚合下面可以增加嵌套聚合)	},	...}

聚合构成

一个聚合的每个 层级 都可以有多个度量或桶

  • Buckets桶 - 足特定条件的文档的集合
  • Metrics指标 - 桶内的文档进行统计计算

聚合方法

  • Buckets桶类(输出桶集,桶内包含统计量)
    • terms 唯一词项分桶(俗称facet特性,高效统计指定层面下各类目约束下的统计量)
    • histogram 数值序列分桶
      • interval: 间隔数值
    • date_histogram 时间序列分桶
      • interval: year|quarter|month|day ...
      • format: yyyy-MM-dd
  • Metrics指标类(输出度量值)
    • min 最小字段值
    • max 最大字段值
    • avg 平均字段值
    • sum 求和字段值
    • stats 字段统计值汇总(包括count、min、max、avg、sum)
    • extended_stats 拓展的字段统计值汇总(stats基础上追加 sum_of_squares平方和、variance方差、std_deviation标准差)

分桶聚合通用参数

  • min_doc_count 指定为0则强制空桶也被返回
  • extended_bounds 扩展分桶的上下限

GEO查询

距离算法distance_type

  • arc 最慢但最精确(球体地球角度)
  • plane 精度性能居中(平坦地球角度)
  • sloppy_arc 最快但最误差(比arc快四五倍,精度99.9%)

圈过滤

{    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 : [
], post_tags : [
], fragment_size: 100, #匹配片段长度 number_of_fragments: 5, #匹配片段数 no_match_size: 0, #无匹配情况下文本长度 } } } }, aggs: { 聚合名: { term: {field: 字段名}, ... aggs: { mySum: {sum: {field:字段名}} } }, ... }, }}

数据建模

关联关系设计

  • 应用层关联 mapping:独立 优缺点:类似于关系型数据库的标准设计,查询性能较差 查询:人工组织关联查询
  • 非规范化文档(适用单个子对象) mapping:共用(子对象:object类型字段,也是字段默认自动映射类型) 文档结构:冗余文档结构,被扁平化为键值结构 优缺点:查询效率较高,但是文档索引过大 查询:使用点语法查询子对象字段
  • 嵌套对象文档(适用多个子对象) mapping:共用(子对象:nested类型字段) 文档结构:冗余文档结构,每一个嵌套对象都会被索引为一个隐藏的独立文档 优缺点:查询效率较高,但是文档索引过大 查询:使用nested语法查询子对象字段
  • 父子关系文档 mapping:独立 文档结构:父对象和子对象都是完全独立的文档 优缺点:索引效率较高,但是查询效率较低 查询:使用has_child、has_parent语法查询父子对象字段

扩容设计

  • 待定

转载于:https://my.oschina.net/u/2400083/blog/908564

你可能感兴趣的文章
Caffe将自己的文件生成lmdb
查看>>
C# 枚举中的位运算
查看>>
Codeforces Global Round 1 晕阙记
查看>>
相机相册
查看>>
百度文化秘籍
查看>>
VSTO Office二次开发对PPT自定义任务窗格测试
查看>>
Algs4-1.3.33一个双向队列Deque-双向链表实现
查看>>
Algs4-2.2.29自然的归并排序(未解决)
查看>>
Python学习——模块的基本知识
查看>>
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
查看>>
shell中数组基础语法
查看>>
P1215 母亲的牛奶
查看>>
DBA_Oracle基本体系内存和进程结构(概念)
查看>>
winform中获取指定文件夹下的所有图片
查看>>
linux学习笔记(四):vi
查看>>
最大连续子序列(dp)
查看>>
mysql触发器trigger
查看>>
谷歌地图API位置请求_Google Maps API
查看>>
20165330 结对编程项目-四则运算 第一周
查看>>
window.showModalDialog
查看>>