elasticSearch
基本概念及特性
概念
- 基于lucene的开源搜索引擎,面向文档(document oriented)的。
- 集群(cluster)
一组具有相同cluster.name的节点集合。
可以在es/config/elasticsearch.yml中修改cluster.name。 - 节点(node)
一个运行着的Elasticsearch的实例。 - 分片(shard)
当有大量文档时,放在一个节点上会收到内存、磁盘等限制。因此需要将数据分成多个分片,放在不同的服务器上。 - 副本(replica)
复制分片是主分片的精确复制,当主分片丢失时,集群自动选择一个复制分片作为新的主分片。
作用:1.容灾 2.提升查询性能和吞吐量
与关系型数据库类比
elasticSearch | 关系型数据库 |
---|---|
index | 数据库 |
type | 表 |
document | 行 |
field | 列 |
文档(document)元数据
- _index
文档存储的地方。
必须是全部小写,不能以下划线开头,不能包含逗号。 - _type
文档代表的对象的分类。
名字可以是大写或小写,不能包含下划线或逗号。
每个类型(type)都有自己的映射(mapping)/结构定义。 - _id
文档的唯一标识。
可自定义,也可由ES自动生成。 - _version
映射
映射(mapping)即是对类型(type)中每个字段的解释说明,将每个字段匹配成一种特定类型。
- ES核心数据类型
- string
- long/integer/short/byte/double/float
- date
- boolean
- binary
- 常用设置
- type
指定字段的数据类型。 - index
- no
不索引当前字段,不能被搜索到。 - analyzed
索引时进行分词分析,全文形式。 - not_analyzed
索引时不进行分词分析,确切值形式。
- no
- include_in_all
- true
默认值。文档所有索引字段自动被加入到_all域中进行索引。因此搜索时不指定域则会从_all中搜索。 - false
此字段不被加入到_all中。这样可以节省建立索引时的CPU开销与内存消耗。
- true
- analyzer
指定建立索引时当前字段使用的分词器。 - search_analyzer
指定搜索时当前字段使用的分词器。未指定时默认使用analyzer指定的分词器。 - norms
设置为false时,评分时不会考虑字段长度归一值,长字段与短字段算作长度相同。
(字段长度归一值见下面相关性评分部分)
- type
分析
分析(analysis)机制用于进行全文文本(Full Text)的分词,以建立供搜索用的反向索引。
- 确切值(exact values)
- 全文文本(full text)
搜索与过滤
做精确匹配搜索时最好用过滤语句,因为过滤语句可以缓存数据。
搜索
- 普通搜索(match_query)
会对搜索词作分词处理,然后检索分别包含各个分词的文档。 - 短语搜索(match_phrase_query)
会对搜索词作分词处理,然后检索同时包含各个分词且相对顺序一致的文档。 - 批量获取(mget)
只能按照索引、类型、ID来批量查询文档。(待确定) - 多字段匹配搜索(multi_match_query)
- bool查询
用来合并多个搜索/查询的结果。
- must(&&)
- must_not(!)
- should(||)
- 普通搜索(match_query)
过滤
- term过滤
不会对搜索词作分词处理。 - terms过滤
过滤匹配一个字段上的多个值。 - range过滤
按指定范围查询数据。 - exist过滤
类似SQL中的exist。 - missing过滤
类似SQL中的ISNULL。 - bool过滤
用来合并多个过滤条件的查询结果的布尔逻辑。
- must(&&)
- must_not(!)
- should(||)
- term过滤
分布式
- 乐观并发控制(Optimistic concurrency control)
分页
集群系统中深度分页的代价很高,需要注意分页设置。
(每个分片中取出,再合并,取出)
排序
https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/tree/cn/170_Relevance
默认排序
- 相关性评分
一个文档的相关度评分部分取决于每个查询词在文档中的权重。权重由以下三个方面影响。
- 词频
词在文档中出现频率越高,权重越高。 - 逆向文档频率
包含词的文档出现频率越高,权重越低。 - 字段长度归一值
字段长度越短,权重越高。
- 词频
- TF/IDF算法
- 布尔模型
- 向量空间模型
自定义评分
改变权重
不建议在建立索引时对字段提升权重,查询时赋予权重是更为简单、清楚、灵活的选择。
- 字段提升权重-boost
- 索引提升权重-indices_boost
- boosting_query
negative_boost: 0 - 1 - constant_score_query
- function_score_query(最强大的方式)
使用此方式可以将文档相关性和最新发布/点赞数/价格等因子综合起来对查询结果进行排序。
预定义函数:
- weight
为文档应用一个不被规范化的权重提升值。(当 weight 为 2 时,最终结果为 2 * _score) - field_value_factor
可以利用点赞数、收藏数等此类数据来影响最终评分。
最终评分 final_score = old_score * 点赞数,对排序结果影响太大。因此可以和以下参数结合使用。
- modifier
用来平滑点赞数对最终评分结果的影响。
final_score = _score* log(1 + 点赞数)
modifier值:none (默认状态)、 log 、 log1p 、 log2p 、 ln 、 ln1p 、 ln2p 、 square 、 sqrt 、reciprocal - factor
用来辅助modifier调节最终评分。
final_score = _score* log(1 + factor * 点赞数) - boost_mode
用来控制函数与查询评分 _score 合并后的结果。
boost_mode值:multiply-评分与_score乘积、sum-评分与_score之和、min-评分与_score较小数、max-评分与_score较大数、replace-评分替换掉_score - max_boost
用来限制函数的影响的最大效果。
- modifier
- random_score
为不同用户使用不同的随机评分影响结果排序,但同一个用户看到的顺序是一样的。 - 衰减函数 —— linear 、 exp 、 gauss
将浮动值结合到评分 _score 中,例如结合 publish_date 获得最近发布的文档,结合 geo_location 获得更接近某个具体经纬度(lat/lon)地点的文档,结合 price 获得更接近某个特定价格的文档。 - script_score
自定义脚本。
ES使用 Groovy 作为默认的脚本语言。
- weight
自定义排序
- sort
对全文字段进行sort操作会耗费大量性能。