ElasticSearch系列三:掌握ES结构化搜索

一、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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值