一、ES的cat api
查看mapping
GET /my_index/_mapping/my_type
检测健康状态
GET _cluster/health
操作索引:
PUT /test_index
DELETE /test_index
GET /test_index
操作文档:
PUT /index/type/id 数据已存在则覆盖
DELETE /index/type/id
POST /index/type/id/_update 更新
GET /index/type/id
注:document的全量替换和删除不会物理删除,只会将其标记为deleted,当数据越来越多的时候,才会在后台自动删除。更新也是这种逻辑。
二、简单案例:对商品进行增删改查
增:
PUT /ecommerce/product/1
{
“name” : “gaolujie yagao”,
“desc” : “gaoxiao meibai”,
“price” : 30,
“producer” : “gaolujie producer”,
“tags”: [ “meibai”, “fangzhu” ]
}
删:
DELETE /ecommerce/product/1
改:
POST /ecommerce/product/1/_update
{
“doc”: {
“name”: “jiaqiangban gaolujie yagao”
}
}
查:
GET /ecommerce/product/1
三、ES的搜索方式
数据准备:
PUT /ecommerce/product/1
{
“name” : “gaolujie yagao”,
“desc” : “gaoxiao meibai”,
“price” : 30,
“producer” : “gaolujie producer”,
“tags”: [ “meibai”, “fangzhu” ]
}
PUT /ecommerce/product/2
{
“name” : “jiajieshi yagao”,
“desc” : “youxiao fangzhu”,
“price” : 25,
“producer” : “jiajieshi producer”,
“tags”: [ “fangzhu” ]
}
PUT /ecommerce/product/3
{
“name” : “zhonghua yagao”,
“desc” : “caoben zhiwu”,
“price” : 40,
“producer” : “zhonghua producer”,
“tags”: [ “qingxin” ]
}
1.query string
例:
GET /ecommerce/product/_search
GET /ecommerce/product/_search?q=yagao
GET /ecommerce/product/_search?q=name:yagao
GET /ecommerce/product/_search?q=+name:yagao name必须包含yagao
GET /ecommerce/product/_search?q=-name:yagao name必须不包含yagao
GET /ecommerce/product/_search?q=name:yagao&sort=price:desc
解释:
took:耗费了几毫秒
timed_out:是否超时
_shards:数据拆成了5个分片,所以对于搜索请求,会打到所有的primary shard(或者是它的某个replica shard也可以)
hits.total:查询结果的数量,3个document
hits.max_score:document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高
hits.hits:包含了匹配搜索的document的详细数据
2.query DSL
例1:查全部:
GET /ecommerce/product/_search
{
“query”: { “match_all”: {} }
}
例2:查询名称包含yagao的商品,同时按照价格降序排序:
GET /ecommerce/product/_search
{
“query” : {
“match” : {
“name” : “yagao”
}
},
“sort”: [
{ “price”: “desc” }
]
}
例3:分页查询商品,总共3条商品,假设每页就显示1条商品,现在显示第2页,所以就查出来第2个商品
GET /ecommerce/product/_search
{
“query”: { “match_all”: {} },
“from”: 1,
“size”: 1
}
例4:指定查询结果字段,查询出商品的名称和价格
GET /ecommerce/product/_search
{
“query”: { “match_all”: {} },
“_source”: [“name”, “price”]
}
例5:多条件案例
每个子查询都会计算一个document针对它的相关度分数,然后bool综合所有分数,合并为一个分数,当然filter是不会计算分数的
GET /ecommerce/product/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“name”: “yagao”
}
}
],
“should”: [
{
“match”: {
“desc”: “gaoxiao”
}
}
],
“must_not”: [
{
“match”: {
“price”: 40
}
}
]
}
}
}
3.query filter
例1:搜索商品名称包含yagao,而且售价大于25元的商品
GET /ecommerce/product/_search
{
“query” : {
“bool” : {
“must” : {
“match” : {
“name” : “yagao”
}
},
“filter” : {
“range” : {
“price” : { “gt” : 25 }
}
}
}
}
}
例2:搜索发帖日期在最近1个月的帖子
GET /forum/article/_search
{
“query”: {
“constant_score”: {
“filter”: {
“range”: {
“postDate”: {
“gt”: “now-30d”
}
}
}
}
}
}
4.full-text search(全文检索)
全文检索会将输入的搜索串拆解开来,去倒排索引里面去一一匹配,只要能匹配上任意一个拆解后的单词,就可以作为结果返回
例:
GET /ecommerce/product/_search
{
“query” : {
“match” : {
“producer” : “yagao producer”
}
}
}
5.phrase search(短语搜索)
跟全文检索相反,要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配,才能作为结果返回
例:
GET /ecommerce/product/_search
{
“query” : {
“match_phrase” : {
“producer” : “jiajieshi producer”
}
}
}
6.term query
term是字段的检索,检索时会按照你输入的内容按照完全匹配的模式检索
GET /ecommerce/product/_search
{
“query”: {
“term”: {
“producer”: “jiajieshi”
}
}
}
7.terms query
GET /ecommerce/product/_search
{
“query”: {
“terms”: {
“tags”: [
“search”,
“fangzhu”,
“zhongyao”
]
}
}
}
8.range query(范围查询)
GET /ecommerce/product/_search
{
“query”: {
“range”: {
“price”: {
“gte”: 30
}
}
}
}
9.multi match(多字段搜索)
GET /ecommerce/product/_search
{
“query”: {
“multi_match”: {
“query”: “producer”,
“fields”: [“producer”, “name”]
}
}
}
10.highlight search(高亮搜索)
例:
GET /ecommerce/product/_search
{
“query” : {
“match” : {
“producer” : “producer”
}
},
“highlight”: {
“fields” : {
“producer” : {}
}
}
}
四、mget批量查询
例1.同index不同type
GET /ecommerce/_mget
{
“docs” : [
{
“_type” : “product”,
“_id” : 1
},
{
“_type” : “product”,
“_id” : 2
}
]
}
例2.同index同type
GET /ecommerce/product/_mget
{
“ids”: [1, 2]
}
五、bulk批量增删改
1.删除一个文档
POST /_bulk
{ “delete”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “3” }}
2.强制创建
POST /_bulk
{ “create”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “12” }}
{ “test_field”:”test12″ }
3.创建文档或全量替换文档
POST /_bulk
{ “index”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “2” }}
{ “test_field”: “replaced test2” }
4.部分更新
POST /_bulk
{ “index”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “2” }}
{ “test_field”: “replaced test2” }
{ “update”: { “_index”: “test_index”, “_type”: “test_type”, “_id”: “1”, “_retry_on_conflict” : 3} }
{ “doc” : {“test_field2” : “bulk test1”} }
注:
①bulk api对json的语法,有严格的要求,每个json串不能换行,只能放一行,同时一个json串和一个json串之间,必须有一个换行
②bulk操作中,任意一个操作失败(多个增删改),是不会影响其他的操作的,但是在返回结果里会有异常日志信息
六、multi-index和multi-type搜索模式
/_search: 所有索引及该type下的所有数据都搜索出来
/index1/_search: 指定一个index,搜索其下所有type的数据
/index1,index2/_search:同时搜索两个index下的数据
/*1,*2/_search: 按照通配符去匹配多个索引
/index1/type1/_search: 搜索一个index下指定的type的数据
/index1/type1,type2/_search:可以搜索一个index下多个type的数据
/index1,index2/type1,type2/_search:搜索多个index下的多个type的数据
/_all/type1,type2/_search:_all代表搜索所有index下的指定type的数据
七、排序规则
1.默认排序规则:按照_score降序排序,某些情况下,可能没有有用的_score,比如说filter
2.按照constant_score(忽略评分)
GET /ecommerce/product/_search
{
“query” : {
“constant_score” : {
“filter” : {
“term” : {
“price” : 40
}
}
}
}
}
2.定制排序规则
GET /ecommerce/product/_search
{
“query”: {
“match_all”: {}
},
“sort”: {
“price”: {
“order”: “desc”
}
}
}
3. _doc
GET /ecommerce/product/_search
{
“query”: {
“match_all”: {}
},
“sort”: [“_doc”]
}
八、scoll滚动查询
1.用于大数据量查询,使用scoll滚动搜索,先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来
2.scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后基于该旧的视图快照提供数据搜索,
3.采用基于_doc进行排序的方式,性能较高
4.每次发送scroll请求,需要指定一个scoll参数,指定一个时间窗口,每次搜索请求只要在这个时间窗口内能完成就可以了
5.例:
GET /test_index/test_type/_search?scroll=1m
{
“query”: {
“match_all”: {}
},
“sort”: [ “_doc” ],
“size”: 3
}
九、基于scoll+bulk+索引别名实现零停机重建索引
描述:重建一个索引,将旧索引的数据查询出来,再导入新索引中,java应用程序不需要停机,零提交,高可用。
①给java应用一个别名,这个别名是指向旧索引的,java应用先用着,java应用先用goods_index alias来操作,此时实际指向的是旧的my_index
PUT /my_index/_alias/goods_index
②新建一个index,调整field的类型等操作
③使用scroll api将数据批量查询出来
④采用bulk api将scoll查出的数据,批量写入新索引
⑤循环5~6到索引数据完成
⑥将goods_index alias切换到my_index_new上去,java应用会直接通过index别名使用新的索引中的数据
POST /_aliases
{
“actions”: [
{ “remove”: { “index”: “my_index”, “alias”: “goods_index” }},
{ “add”: { “index”: “my_index_new”, “alias”: “goods_index” }}
]
}
⑦通过goods_index别名来查询
GET /goods_index/my_type/_search