侧边栏壁纸
  • 累计撰写 101 篇文章
  • 累计创建 89 个标签
  • 累计收到 9 条评论

elasticsearch笔记 - DSL搜索

bearjun
2021-01-07 / 0 评论 / 0 点赞 / 1,398 阅读 / 10,183 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-01-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

src=http___bigdataboutique.com_images_courses_elasticsearch-whitebg.png&refer=http___bigdataboutique.jpg

中文文档

中文文档地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/getting-started.html

基本查询(queryString)

基本语法/index/_doc/_search?q=key:value

  • inde 索引
  • _doc/_search?q= 指定格式
  • key:value key文档中的内容 value 搜索的内容
//查询shop索引中文档的desc包含bearjun博客
GET     /shop/_doc/_search?q=desc:bearjun博客
//查询shop索引中文档的desc包含bearjun博客并且age为25
GET     /shop/_doc/_search?q=nickname:bearjun博客&q=age:25

DSL基本语法

语法格式为一个json对象,内容都是key-value键值对,json可以嵌套。
key可以是一些es的关键字,也可以是某个field字段,后面会遇到

// 查询
POST  /shop/_doc/_search 
// 等价于
GET  /shop/_doc/_search?q=desc:bearjun博客 
{
    "query": {
        "match": {
            "desc": "bearjun博客"
        }
    }
}
//  判断某个字段是否存在
{
    "query": {
        "exists": {
            "field": "desc"
        }
    }
}

分页

根节点加入 "from": 0, "size": 10
from 从第几页开始(pageIndex)
size 每一页的条数 (pageSize)
es的默认分页是10

POST     /shop/_doc/_search
{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 10
}
 
{
    "query": {
        "match_all": {}
    },
    //_source,查询那些字段信息
    //相当于select id,nickname,age from xxx
    "_source": [
        "id",
        "nickname",
        "age"
    ],
    "from": 5, 从第几条数据开始
    "size": 5  数据的大小
}

term、match、terms

term 精确搜索(不分词,输入内容作为查询内容,有点像mapping的keyword和text)
match 分词搜索(根据分词器分词查询,查询分词后的内容)
terms 多个词语匹配检索(多词查询,数组形式)

POST     /shop/_doc/_search
//term
{
    "query": {
        "term": {
           //这个地方会找desc包含慕课网的的文档
            "desc": "慕课网"
        }
    }
}
//match
{
    "query": {
        "match": {
            //mapping配置的是ik分词
            //这个地方会找desc包含慕课、慕课网、慕、课、网的文档
            "desc": "慕课网"
        }
    }
}
//terms
{
    "query": {
        "terms": {
           //这个地方会找desc包含慕课、慕课网、慕、课、网的文档
            "desc": ["慕课网","慕课","慕","课","网","课网"]
        }
    }
}

需要注意的是

{
    "query":{
        "term":{
           //name 的type是 text 需要加上keyword才能精准匹配
           "name.keyword":"imooc-3"
        }
    }
}

match_phrase

短语匹配: 分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。
格式:"query" : "xxx xxx xxx"(搜索比较严格)

POST     /shop/_doc/_search
{
    "query": {
        "match_phrase": {
            "desc": {
                //查询desc中包含大学 毕业 研究生,且按照这个顺序的文档
                "query": "大学 毕业 研究生",
                //允许词语间跳过的数量(大学和毕业中间最多允许2个词,且毕业和研究生也一样,中间最多允许2个词)
                "slop": 2
            }
        }
    }
}

match(operator)

前面说的match是分词之后全匹配,那如果要匹配某一个,或者某些呢?
or 搜索内容分词后,只要存在一个词语匹配就展示结果
and 搜索内容分词后,都要满足词语匹配
minimum_should_match 最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整,当然,也可以是一个数字

or、and

POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    }
}
// 等同于
{
    "query": {
        "match": {
            "desc": {
                "query": "xbox游戏机",
                // or:搜索内容分词后,只要存在一个词语匹配就展示结果
                // and:搜索内容分词后,都要满足词语匹配
                "operator": "or|and"
            }
        }
    }
}
// 相当于 select * from shop where desc='xbox' or|and desc='游戏机'

minimum_should_match

POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": {
                "query": "女友生日送我好玩的xbox游戏机",//(想屁吃)
                //对query的内容进行分词,然后用分词后的数量乘以百分比向下取整进行匹配
                "minimum_should_match": "60%"
                //这个也可以是数值,代表分词后的数量整进行匹配
                //"minimum_should_match": "6"
            }
        }
    }
}

ids

根据文档主键ids搜索

GET  /shop/_doc/id
//相当于
POST     /shop/_doc/_search
 {
    "query": {
        "ids": {
            "type": "_doc",
            "values": ["1001", "1010", "1008"]
        }
    }
 }

multi_match

multi_match 满足使用match在多个字段中进行查询的需求
boost 权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。

POST     /shop/_doc/_search
{
    "query": {
        "multi_match": {
            "query": "皮特帕克慕课网",
            "fields": ["desc", "nickname"]
            //如果需要nickname的权重比desc高(加^10即可)
            "fields": ["desc", "nickname^10"]
        }
    }
}

布尔(bool)查询

must、should、must_not

must 查询必须匹配搜索条件,譬如 and
should 查询匹配满足1个以上条件,譬如 or
must_not 不匹配搜索条件,一个都不要满足

POST     /shop/_doc/_search
 
{
    "query": {
        "bool": {
            //搜索三个条件同时满足的情况
            "must": [
                {
                    "multi_match": {
                        "query": "慕课网",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "term": {
                        "sex": 1
                    }
                },
                {
                    "term": {
                        "birthday": "1996-01-14"
                    }
                }
            ]
        }
    }
}
 
{
    "query": {
        "bool": {
            //should   搜索三个条件只满足其中一个即可
            //must_not 搜索三个条件都不满足
            "should(must_not)": [
                {
                    "multi_match": {
                        "query": "学习",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "match": {
                        "desc": "游戏"
                    }   
                },
                {
                    "term": {
                        "sex": 0
                    }
                }
            ]
        }
    }
}

[tag type="default"]当然,must、should、must_not可以叠加使用[/tag]
布尔(bool)组合加权查询,给指定的关键字加权,类似于百度搜索,大家都懂。

POST     /shop/_doc/_search
//查询搜索desc包含慕课或者bearjun的文档
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "desc": {
                            "query" : "慕课",
                            //给搜索结果的分数加权
                            "boost" : "2"
                         }
                    }   
                },
                {
                    "match": {
                        "desc": {
                            "query" : "bearjun",
                            //给搜索结果的分数加权
                            "boost" : "100"
                         }
                    }   
                },
            ]
        }
    }
}

post_filter过滤器

对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。

  • gte 大于等于(greater than or equal)
  • lte 小于等于(less than or equal)
  • gt 大于(greater than)
  • lt 小于(less than)
POST     /shop/_doc/_search
 
{
    //去es库里面搜索
    "query": {
        "match": {
            "desc": "慕课网游戏"
        }   
    },
    //对搜索的内容过滤
    "post_filter": {
        //搜索的范围(关键字)
        "range(term)": {
            //过滤金额大于60小于1000的文档
            //这个搜索是在搜索结果之后的过滤
            "money": {
                "gt": 60,
                "lt": 1000
            }
        }
    }   
}

sort排序

对数据排序

  • asc 正序(从小到大)
  • desc 倒序(从大到小)
POST     /shop/_doc/_search
 
{
    "query": {
        "match": {
            "desc": "慕课网游戏"
        }   
    },
    "sort": [
       {
          "age":"desc"
       },
       {
           "birthday":"asc"
       }, 
       //需要注意的是:当某个mapping的类型是text时
       {
           "desc.keyword":"asc"
       }
    ]
}

highlight高亮

查看淘宝或者百度,高亮就是添加相应的标签即可,高亮默认是em标签

POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    },
    //高亮的关键字,默认是<em></em>标签
    "highlight": {
        //高亮的关键字前缀
        "pre_tags": ["<tag>"],
        //高亮的关键字后缀
        "post_tags": ["</tag>"],
        "fields": {
            "desc": {}
        }
    }
}

深度分页

当搜索深度比较大的时候,例如搜索第10000条,第100000条的时候,es默认的最大搜索条数max_result_window为10000,也就是当搜索大于10000的时候,会报错。

当我们去淘宝或者百度搜索的时候,发现他们有意的规避深度搜索的问题,其中淘宝的最大搜索页数是100,而百度的最大搜索页数小于100,google更过分,我输入的关键字,尽然没有超过30页的,所以,深度搜索我们可以通过技术手段来进行规避。
当然,也可以通过提升搜索量:通过设置index.max_result_window来突破10000数据的限制

//发送请求获取es的设置
GET     /shop/_settings
 
//发送请求设置max_result_window
PUT     /shop/_settings
{ 
    "index.max_result_window": "20000"
}

scroll 滚动搜索(游标搜索)

滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个锚标记,随后再次滚动搜索会需要上一次搜索的锚标记,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的,搜索的内容还是快照中的数据。
官方文档地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html

//相当于是一个session会话时间,搜索保持的上下文时间为1分钟
POST    /shop/_search?scroll=1m
{
    "query": { 
        "match_all": {
        }
    },  
    "sort" : ["_doc"], 
    "size":  5
}
 
POST    /_search/scroll
{
    //相当于是一个session会话时间,搜索保持的上下文时间为1分钟
    "scroll": "1m", 
    "scroll_id" : "your last scroll_id"
}

[tag type="default"]该功能可以用于大数据导出[/tag]

mget 批量查询

批量查询数据

前面我们学习了ids查询,通过ids可以批量的查询数据,那mget和ids有什么区别呢?

GET   /shop/_doc/_mget
{
      "ids":["1001","1002"]
 
}

//搜索结果
{
    "docs": [
        {
            "_index": "shop",
            "_type": "_doc",
            "_id": "1001",
            "_version": 1,
            "_seq_no": 0,
            "_primary_term": 1,
            // true表示有数据,false表示没有数据
            "found": true,
            "_source": {
                "id": 1001,
                "age": 18,
                "username": "imoocAmazing",
                "nickname": "慕课网",
                "money": 88.8,
                "desc": "我在慕课网学习java和前端,学习到了很多知识",
                "sex": 0,
                "birthday": "1992-12-24",
                "face": "https://www.imooc.com/static/img/index/logo.png"
            }
        },
        {
         ........
        }
    ]
}

我们发现,mget搜索的只是和内容相关的,而ids还包括一切索引信息,json对象比较冗余。

bulk 批量操作

bulk操作和以往的普通请求格式有区别。不要格式化json,不然就不在同一行了,这个需要注意。
文档地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/bulk.html

 action: { metadata }}\n
{ request body        }\n
{ action: { metadata }}\n
{ request body        }\n
  • { action: }代表批量操作的类型,可以是新增、删除或修改
  • \n是每行结尾必须填写的一个规范,每一行包括最后一行都要写,用于es的解析
  • 是请求body,增加和修改操作需要,删除操作则不需要

bulk之create

create新增文档数据,在metadata中指定index以及type

POST    /_bulk
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2001"}}
{"id": "2001", "nickname": "name2001"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2002"}}
{"id": "2002", "nickname": "name2002"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2003"}}
{"id": "2003", "nickname": "name2003"}

create创建已有id文档,在url中指定index和type

POST    /shop/_doc/_bulk
{"create": {"_id": "2003"}}
{"id": "2003", "nickname": "name2003"}
{"create": {"_id": "2004"}}
{"id": "2004", "nickname": "name2004"}
{"create": {"_id": "2005"}}
{"id": "2005", "nickname": "name2005"}

index创建,已有文档id会被覆盖,不存在的id则新增

POST    /shop/_doc/_bulk
{"index": {"_id": "2004"}}
{"id": "2004", "nickname": "index2004"}
{"index": {"_id": "2007"}}
{"id": "2007", "nickname": "name2007"}
{"index": {"_id": "2008"}}
{"id": "2008", "nickname": "name2008"}

bulk之update

update更新部分文档数据

POST    /shop/_doc/_bulk
{"update": {"_id": "2004"}}
{"doc":{ "id": "3004"}}
{"update": {"_id": "2007"}}
{"doc":{ "nickname": "nameupdate"}}

bulk之delete

delete批量删除

POST    /shop/_doc/_bulk
{"delete": {"_id": "2004"}}
{"delete": {"_id": "2007"}}

POST    /shop/_doc/_bulk
{"create": {"_id": "8001"}}
{"id": "8001", "nickname": "name8001"}
{"update": {"_id": "2001"}}
{"doc":{ "id": "20010"}}
{"delete": {"_id": "2003"}}
{"delete": {"_id": "2005"}}
0

评论区