勿以浮沙筑高台
elasticsearch的基本使用
Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的。
对比关系:
索引(indices)--------------------------------Databases 数据库
类型(type)-----------------------------Table 数据表
文档(Document)----------------Row 行
字段(Field)-------------------Columns 列
要注意的是:Elasticsearch本身就是分布式的,因此即便你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。
基础语法
- 建立索引(表)
PUT /mr_fu # 索引名 { "settings": { "number_of_shards": 1, # 分片 "number_of_replicas": 1 # 从节点 } }
- 查看索引(表)
GET /mr_fu # 索引库名
- 删除索引(表)
DELETE /索引库名
- 建立映射(设置字段)
PUT /索引库名/_mapping/类型名称?include_type_name=true PUT /mr_fu/_mapping/users?include_type_name=true { "properties": { "name": { #名称 "type": "text", # 类型 # ndex影响字段的索引情况。 true:字段会被索引,则可以用来进行搜索。默认值就是true false:字段不会被索引,不能用来搜索 index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引。 "index": true, # 是否索引,默认为true # 让外部能否查询到 就算设置了false,elasticsearch也会存储一份数据到_source当中,而且我们可以通过 过滤 _source 来选择哪些要显示,哪些不显示。如果设置store为true,就会在 _source 以外额外存储一份数据,多余了所以默认为false 默认是false, "store": true, # 是否存储,默认为false "analyzer": "ik_smart" #分词器 } } }
- 查看索引映射(查看字段)
GET /索引库名/_mapping GET /mr_fu/_mapping
- 新增数据(插入数据)
POST /索引名/映射名/ POST /mr_fu/users/ { "name":"负差生" # 属性 值 } POST /索引名/映射名/ID POST /mr_fu/users/1 { "name":"负差生" # 属性 值 }
- 查询
GET /库名/_search GET /mr_fu/_search GET /索引名/映射名/ID GET /mr_fu/_search/1 GET /mr_fu/users/1?_source=age #查询某个字段 GET /mr_fu/users/1?_source=age,name #查询多个某个字段 GET /mr_fu/users/1/_source #只查询数据信息
- 修改数据
POST /索引名/映射名/ID/_update?pretty=true POST /mr_fu/users/1/_update?pretty=true { # 如果字段不存在,修改会新增字段 "doc":{"name":"AAA"} # key value }
- 删除数据
DELETE /索引库名/类型名/id
复杂语法
- 增
# 批量添加数据_bulk POST /mr_fu/users/_bulk { "index": { "_id": 1 }} { "name" : "王二麻子","age" :20} { "index": { "_id": 2 }} { "name" : "李四B","age" :5 } { "index": { "_id": 3 }} { "name" : "张三","age" :38 } { "index": { "_id": 4 }} { "name" : "李四","age" :59 } { "index": { "_id": 5 }} { "name" : "张三AAA","age" :38 }
- 查
# 带条件的简单条件查询 # 多个参数用& GET /mr_fu/users/_search?q=name:王二 # 模糊查询 # match关键字 # match关键字查询,会分词进行完全匹配,分词即分为张三和AAA,必须完全匹配 # 比如说现在数据库里有张三和张三AAA2个数据 # 执行下面代码会查询出2个张三,即张三AAA和张三 GET /mr_fu/users/_search # match关键字查询 { "query": { "match": { "name": "张三AAA" } } } # or和an查询 # match operator关键字 GET /mr_fu/users/_search { "query": { "match": { "tages":{ "query":"程序猿 菜鸟 ", "operator":"or", # or或and,查询出tages中只要包含菜鸟和程序猿的的数据 "minimum_should_match":2 #精确度,满足2个条件 } } } } # multi_match查询,多个字段包含相同值 GET /mr_fu/users/_search { "query": { "multi_match": { "query": "直", "fields": ["tages","name"] } } } # 字符 说明 # gt 大于 # gte 大于等于 # lt 小于 # lte 小于等于 GET /mr_fu/users/_search { "query": { "range": { "age": { "gt": 6, # 大于6 "lt": 60 # 小于60 } } } } # term 关键字不分词查询 GET /mr_fu/users/_search { "query": { "term": { "age": { "value": "38" #查询等于38的 } } } } # terms 多关键字不分词查找 GET /mr_fu/users/_search { "query": { "terms": { "age": ["5","38"] } } } # exists 查询 # 查询包含字段为name的值 GET /mr_fu/users/_search { "query": { "bool": { "filter": { "exists": { "field": "name" } } } } } # match_phrase查询 # 不分词匹配包含查询字段的文档 GET /mr_fu/users/_search { "query": { "match_phrase": { "tages": "攻城狮" } } } # fuzzy查询 # 模糊查询, fuzzy 查询会计算与关键词的拼写相似程度 # fuzziness:最大编辑距离,默认为 AUTO # prefix_length:不会“模糊化”的初始字符数。这有助于减少必须检查的术语数量,默认为 0 # max_expansions: fuzzy 查询将扩展到 的最大术语数。默认为 50 ,设置小,有助于优化查询 # transpositions:是否支持模糊转置( ab → ba ),默认是 false GET /mr_fu/users/_search { "query": { "fuzzy": { "tages":{ "value": "攻城时", "fuzziness": 2, "prefix_length": 1 } } } } #查询所有 GET /mr_fu/users/_search { "query": { "match_all":{ } } } # 分页查询 # from起始点 # 从其实点开始查询的条数 # 不要使用fromsize进行深度分页,因为它会到之前的所有数据进行查询排序,再取我们需要的数据 GET /mr_fu/users/_search { "query": { "match_all": {} }, "from": 1, "size": 2 } # _source指定查询的字段 GET /mr_fu/users/_search { "query": { "match_all": {} }, "_source": ["name","tages"] }
聚合查询
类似mysql中的groupby
Elasticsearch中的聚合,包含多种类型,最常用的两种,一个叫 桶 ,一个叫 度量 :桶的作用就算进行划分,汽车桶,飞机桶,坦克桶…
分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在ES中称为 度量。
常用桶值
- Elasticsearch中提供的划分桶的方式有很多: Date Histogram
- Aggregation:根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组Histogram
- Aggregation:根据数值阶梯分组,与日期类似 Terms Aggregation:根据词条内容分组,词条内容完全匹配的为一组
- Range Aggregation:数值和日期的范围分组,指定开始和结束,然后按段分组
常用度量值
-
Avg Aggregation:求平均值
-
Max Aggregation:求最大值
-
Min Aggregation:求最小值
-
Percentiles Aggregation:求百分比
-
Stats Aggregation:同时返回avg、max、min、sum、count等
-
Sum Aggregation:求和
-
Top hits Aggregation:求前几
-
Value Count Aggregation:求总数
-
导入数据
POST /cars/_doc/_bulk { "index": {}} { "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" } { "index": {}} { "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" } { "index": {}} { "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" } { "index": {}} { "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" } { "index": {}} { "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" } { "index": {}} { "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" } { "index": {}} { "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" } { "index": {}} { "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }
-
按颜色划分桶
# size: 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率 # aggs:声明这是一个聚合查询,是aggregations的缩写 # popular_colors:给这次聚合起一个名字,任意。 # terms:划分桶的方式,这里是根据词条划分 # field:划分桶的字段 GET /cars/_search { "size" : 0, "aggs" : { "popular_colors" : { "terms" : { "field" : "color" } } } }
-
给桶添加度量
# avg:度量的类型,这里是求平均值 # field:度量运算的字段 GET /cars/_search { "size" : 0, "aggs" : { "popular_colors" : { "terms" : { "field" : "color" }, "aggs":{ "avg_price": { "avg": { "field": "price" } } } }
-
给桶内嵌套桶
GET /cars/_search { "size" : 0, "aggs" : { "popular_colors" : { "terms" : { # 按颜色分桶 "field" : "color" }, "aggs":{ "avg_price": { "avg": { # 平均数 "field": "price" } }, "maker":{ # 添加桶内桶 "terms":{ # 匹配字段 "field":"make" #make字段分组 } } } } } }