中文文档
中文文档地址: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"}}
评论区