ElasticSerach DSL基本语法

请求参数的查询(QueryString)

查询[字段]包含[内容]的文档

GET请求     http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅
GET请求     http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅&q=age:18

这种方式一般称之为QueryString查询方式,参数都是在URL中作为请求参数的。

点击一下,咻的一下就可以查看官方文档了,可直接翻译es DSL操作官方文档

DSL基本语法

QueryString用的很少,一旦参数复杂就很难构建,所以大多数查询都是使用dsl来进行查询比较好。

  • Domain Specific Language
  • 特定领域语言
  • 基于JSON格式的数据查询
  • 查询更灵活,有利于复杂查询

1、match语法

  #查询
 POST   http://192.168.1.181:9200/shop/_doc/_search
 {
    "query":{
        "match":{
            "desc":"我真帅"
        }
    }
}
# 同等于: GET  http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅

#判断某个字段是否存在
{
    "query":{
        "exists":{
            "field":"desc"
        }
    }
}

!补充:语法格式为一个json object,内容都是key-value键值对,json可以嵌套。 key可以是一些es的关键字,也可以是某个field字段

2、match_all

在索引中查询所有的文档

  GET http://113.98.58.50:9200/shop/_doc/_search  
  
  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query":{
        "match_all":{}
    },
    "_source":["id","nickname","age"], # 类似mysql中select * 替换
    "from": 0,   # 从那一条数据开始
    "size": 10   # 每一页展示多少条数据
}

3、match_phrase

match:分词后只要有数据就会进行匹配然后返回
match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的(搜索相对而言比较严格)

  # slop:允许词语间跳过的数量
  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "match_phrase": {
            "desc": {
                "query": "大学 毕业 研究生",
                "slop": 2
            }
        }
    }
}

4、match 扩展

operator:

  • or:搜索内容分词后,只要存在一个词语匹配就能有结果
  • and:搜索内容分词后,都要满足词语匹配
 POST  http://113.98.58.50:9200/shop/_doc/_search
{
 "query": {
     "match": {
         "desc": "我真帅!"
     }
 }
}
# 等同于
{
 "query": {
     "match": {
         "desc": {
             "query": "xbox游戏机",
             "operator": "or"
         }
     }
 }
}
# 相当于 select * from shop where desc='xbox' or|and desc='游戏机'
  • minimum_should_match:最低匹配精度,至少有[分词后的词语个数]百分位,的出一个数据值取整。举个🌰:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度就是1070%=7,则desc中至少需要有7个成语进行匹配,就展示。若分词后有八个,则8*70% =5.6,则desc中至少需要有5个成语匹配,就展示。
  • minimum_shodld_match 也能设置具体的数字,表示个数
POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "match": {
            "desc": {
                "query": "女友在我生日的时候送了我一双限量版球鞋,可把我开心坏了。",
                "minimum_should_match": "60%"
            }
        }
    }
}

根据文档主键ids搜索

#查询当个
GET /shop/_doc/1001
#查询多个
POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "ids": {
            "type": "_doc",
            "values": ["1001", "1010", "1008"]
        }
    }
}

5、multi_match/boost

#满足使用match在多个字段中进行查询的需求
  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "multi_match": {
                "query": "王二  18",
                "fields": ["name", "age"]
        }
    }
}

#boost
#权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。
{
    "query": {
        "multi_match": {
                "query": "王二  18",
                "fields": ["name", "age^10"]

        }
    }
}
#age^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个age为主,name为辅,age的匹配相关度当然要提高权重比例了。

6、term

搜索的时候会吧用户搜索内容,比如:"你是真的丑爆了!"作为一个整体的关键字去搜索,而不会对其他的分词后在搜索。

  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query":{
        "term":{
            "desc":"你是真的丑爆了!"
        }
    }
}
# 可以对比:
{
    "query": {
        "match": {
            "desc": "你是真的丑爆了!"
        }
    }
}

# terms 多个词语匹配检索
# 相当于是tag标签查询,比如慕课网的一些淘宝会打上衣服、裤子、鞋子、袜子这样的标签,可以完全匹配做类似标签的查询
 {
    "query":{
        "terms":{
            "desc":["衣服","裤子","鞋子"]
        }
    }
}

!注:match会对"你是真的丑爆了!"些进行分词(其实就是全文搜索),在查询,而term则不会,直接吧"你是真的丑爆了!"作为一个整的词汇去搜索。

6、布尔查询

可以组合多重查询

  • must:查询必须匹配搜索条件,比如and
  • should: 查询匹配满足1个以上条件,比如or
  • must_not:不匹配搜索条件,一个都不需要满足
  POST  http://113.98.58.50:9200/shop/_doc/_search
实操1:
{
    "query": {
        "bool": {
            "must": [
                {
                    "multi_match": {
                        "query": "我可真帅",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "term": {
                        "sex": 1
                    }
                },
                {
                    "term": {
                        "birthday": "1996-01-14"
                    }
                }
            ]
        }
    }
}

{
    "query": {
        "bool": {
            "should(must_not)": [
                {
                    "multi_match": {
                        "query": "学习",
                        "fields": ["desc", "nickname"]
                    }
                },
                {
                    "match": {
                        "desc": "游戏"
                    }   
                },
                {
                    "term": {
                        "sex": 0
                    }
                }
            ]
        }
    }
}

实操2:
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "desc": "爱"
                    }   
                },
                {
                    "match": {
                        "nickname": "爱"
                    }   
                }
            ],
            "should": [
                {
                    "match": {
                        "sex": "0"
                    }   
                }
            ],
            "must_not": [
                {
                    "term": {
                        "birthday": "1998-12-24"
                    }   
                }
            ]
        }
    }
}

#为指定词语加权
#特殊场景下,某些词语可以单独加权,这样可以排得更加靠前。
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "desc": {
                            "query": "律师",
                            "boost": 18
                        }
                    }
                },
                {
                    "match": {
                        "desc": {
                            "query": "进修",
                            "boost": 2
                        }
                    }
                }
            ]
        }
    }
}

7、过滤器

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

post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分数去排序。

使用场景:

  • query:根据用户搜索条件检索匹配记录
  • post_filter:用于查询后,对结果数据的筛选

实操:查询账户金额大于80元,小于160元的用户。并且生日在1998-07-14的用户

  • gte:大于等于
  • lte:小于等于
  • gt:大于
  • lt:小于
    (除此以外还能做其他的match等操作也行)
  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "玩吃鸡滴滴我呀!我钢枪贼6"
        }   
    },
    "post_filter": {
        "range": {
            "money": {
                "gt": 60,
                "lt": 1000
            }
        }
    }   
}

8、排序

es的排序同sql,可以desc也可以asc。也支持组合排序。

实操:

  POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "玩吃鸡滴滴我呀!我钢枪贼6"
        }
    },
    "post_filter": {
        "range": {
            "money": {
                "gt": 55.8,
                "lte": 155.8
            }
        }
    },
    "sort": [
        {
            "age": "desc"
        },
        {
            "money": "desc"
        }
    ]
}

对文本排序

由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。

  • 创建新的索引
POST        /shop2/_mapping
{
    "properties": {
        "id": {
            "type": "long"
        },
        "nickname": {
            "type": "text",
            "analyzer": "ik_max_word",
            "fields": {
                "keyword": {
                    "type": "keyword"
                }
            }
        }
    }
}
  • 插入数据
POST         /shop2/_doc
{
    "id": 1001,
    "nickname": "美丽的风景"
}
{
    "id": 1002,
    "nickname": "漂亮的小哥哥"
}
{
    "id": 1003,
    "nickname": "飞翔的巨鹰"
}
{
    "id": 1004,
    "nickname": "完美的天空"
}
{
    "id": 1005,
    "nickname": "广阔的海域"
}
  • 排序
{
    "sort": [
        {
            "nickname.keyword": "desc"
        }
    ]
}

9、高亮highlight

高亮显示

 POST  http://113.98.58.50:9200/shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "你真帅"
        }
    },
    "highlight": {
        "pre_tags": ["<tag>"],
        "post_tags": ["</tag>"],
        "fields": {
            "desc": {}
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342