ElasticSearch系列文章四 DSL搜索

DSL搜索

数据准备
  • 自定义词库

    • 马可波罗
    • 马可
    • 波罗
  • 建立索引 demeter_index

  • 手动建立mappings

    POST /demeter_index/_mapping
    {
      "properties": {
        "id": {
          "type": "long"
        },
        "age": {
          "type": "integer"
        },
        "username": {
          "type": "keyword"
        },
        "nickname": {
          "type": "text",
          "analyzer": "ik_max_word",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          }
        },
        "money": {
          "type": "float"
        },
        "desc": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "sex": {
          "type": "byte"
        },
        "birthday": {
          "type": "date"
        },
        "face": {
          "type": "text",
        "index": false
        }
    }
    }
    

    添加数据

    POST /demeter_index/_doc/1001
    {
      "id": 1001,
      "age": 18,
      "username": "demeter",
      "nickname": "马可",
      "money": 88.8,
      "desc": "我叫马可波罗,很马兴认识大家",
    "sex": 0,
      "birthday": "1992-12-24",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1002
    {
      "id": 1002,
      "age": 19,
      "username": "sulliven",
      "nickname": "波罗",
      "money": 77.8,
      "desc": "今天太阳很大,马路上没有行人",
    "sex": 1,
      "birthday": "1993-01-24",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1003
    {
      "id": 1003,
      "age": 20,
      "username": "paul",
      "nickname": "马可波罗",
      "money": 66.8,
      "desc": "马可波罗来中国历险",
    "sex": 1,
      "birthday": "1996-01-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1004
    {
      "id": 1004,
      "age": 22,
      "username": "sky",
      "nickname": "云中君",
      "money": 55.8,
      "desc": "羊吃草,马儿跑",
    "sex": 0,
      "birthday": "1988-02-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1005
    {
      "id": 1005,
      "age": 25,
      "username": "tiger",
      "nickname": "裴擒虎",
      "money": 155.8,
      "desc": "我今天玩了一局王者荣耀",
    "sex": 1,
      "birthday": "1989-03-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1006
    {
      "id": 1006,
      "age": 19,
      "username": "misscodedemeter",
      "nickname": "小罗",
      "money": 156.8,
      "desc": "我叫罗某某,今年20岁,是一名学生",
    "sex": 1,
      "birthday": "1993-04-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1007
    {
      "id": 1007,
      "age": 19,
      "username": "cat",
      "nickname": "小小",
      "money": 1056.8,
      "desc": "这是我第一天学习elasticsearch",
    "sex": 1,
      "birthday": "1985-05-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1008
    {
      "id": 1008,
      "age": 19,
      "username": "mark",
      "nickname": "小天",
      "money": 1056.8,
      "desc": "大学毕业后,来到一家开发公司工作",
    "sex": 1,
      "birthday": "1995-06-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1009
    {
      "id": 1009,
      "age": 22,
      "username": "tim",
      "nickname": "大菠萝",
      "money": 96.8,
      "desc": "阿罗在大学毕业后,考研究生去了",
    "sex": 1,
      "birthday": "1998-07-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1010
    {
      "id": 1010,
      "age": 30,
      "username": "gaga",
      "nickname": "可心",
      "money": 100.8,
      "desc": "我在学习kibana",
    "sex": 1,
      "birthday": "1988-07-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1011
    {
      "id": 1011,
      "age": 31,
      "username": "sprder",
      "nickname": "知事",
      "money": 180.8,
      "desc": "能让我尊重的新闻媒体不多了",
    "sex": 1,
      "birthday": "1989-08-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
    POST /demeter_index/_doc/1012
    {
      "id": 1012,
      "age": 31,
      "username": "super hero",
      "nickname": "super hero",
      "money": 188.8,
      "desc": "BatMan, GreenArrow, SpiderMan, IronMan... are all Super Hero",
      "sex": 1,
      "birthday": "1980-08-14",
      "face": "https://www.codedemeter.com/static/img/index/logo.png"
    }
    
入门语法

请求参数的查询(QueryString)

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

在这里插入图片描述

text与keyword搜索对比测试(keyword不会被倒排索引,不会被分词)username对应的是keyword,nickname对应的是text.

GET /demeter_index/_doc/_search?q=nickname:马克

在这里插入图片描述

GET /demeter_index/_doc/_search?q=username:meter

在这里插入图片描述

GET /demeter_index/_doc/_search?q=username:demeter

在这里插入图片描述

DSL基本语法

QueryString用的很少,一旦参数复杂就难以构建,所以大多数查询都会使用dsl来查询。

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

DSL格式语法

#查询
POST /demeter_index/_doc/_search
{
  "query":{
    "match":{
      "desc":"学习"
    }
  }
}
#判断某字段是否存在
POST /demeter_index/_doc/_search
{
    "query": {
        "exists": {
            "field": "desc"
        }
    }
}
  • 语法格式为一个json object,内容都是key-value键值对,可以嵌套
  • key可以是es的关键字,也可以是某个field字段
查询与分页

查询所有 match_all

POST /demeter_index/_doc/_search
{
    "query": {
        "match_all": {}
    }
}

只想显示一些field可以设置_source

POST /demeter_index/_doc/_search
{
  "query": {
    "match_all": {}
  },
  "_source": [
    "id",
    "nickname",
    "age",
    "desc"
  ]
}
在这里插入图片描述

分页查询,默认查询是只有10条记录,可以通过分页来展示,设置from(从第几条开始) size(查询几条)

POST /demeter_index/_doc/_search
{
"query": {
 "match_all": {}
  },
   "_source": [
   "id",
   "nickname",
    "age",
    "desc"
   ],
   "from": 0,
  "size": 5
  }
在这里插入图片描述
term与match区别

term精确搜索与match分词搜索

term是代表完全匹配,也就是精确查询,搜索前不会再对搜索词进行分词,所以搜索必须是文档分词集合中的一个

POST /demeter_index/_doc/_search
{
  "query": {
    "term": {
      "nickname":"马可"
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}

查询到两条

在这里插入图片描述

match查询会对搜索词进行分词,只要搜索词的分词集合中的一个或多个存在与文档中就会被查询到

POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "nickname":"马可"
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}

查询到3条

在这里插入图片描述

terms 多个词语匹配检索

查询某个字段里含有多个关键词的文档

POST /demeter_index/_doc/_search
{
  "query": {
    "terms": {
      "nickname":["马可","波罗"]
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
在这里插入图片描述
match_phrase

match_phrase 短语匹配,match分词后只要有匹配就返回,match_phrase分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。

POST /demeter_index/_doc/_search
{
  "query": {
    "match_phrase": {
      "desc":{
        "query":"第一天 学习"
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
在这里插入图片描述

slop:允许词语间跳过的数量

{
  "query": {
    "match_phrase": {
      "desc":{
        "query":"我 学习",
        "slop": 1
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
在这里插入图片描述
match(operator)/ids

match扩展 operator

  • or:搜索内容分词后,只要存在一个词语匹配就展示结果
  • and:搜索内容分词后,都要满足词语匹配
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc":"我 学习"
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
#等同于
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc":{
        "query":"我 学习",
        "operator":"or"
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
在这里插入图片描述
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc":{
        "query":"我 学习",
        "operator":"and"
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}

在这里插入图片描述
  • minimum_should_macth:最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整,举个例子:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度按照10x70%=7,则desc中至少有7个词语匹配,就展示,若分词后有8个词语,8x70%=5.6,则desc中至少需要5个词语匹配就展示。
  • minimum_should_macth也可以设置具体的数字,表示个数
# 查询检索内容的分词结果 
POST /_analyze
{
  "analyzer": "ik_max_word",
  "text": "我学习了redis和docker"
}
#分词后共有6个词语
#我 学习 了 redis 和 docker
#6*40%=2.4 需要满足两个词语匹配
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc":{
        "query":"我学习了redis和docker",
        "minimum_should_match":"40%"
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}
在这里插入图片描述
# 需要满足两个词语匹配 结果如上图
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc":{
        "query":"我学习了redis和docker",
        "minimum_should_match":2
      }
    }
  },
  "_source": [
    "id",
    "nickname",
    "desc"
  ]
}

ids 根据文档主键ids搜索

GET /demeter_index/_doc/1001

查询多个

POST /demeter_index/_doc/_search
{
    "query": {
        "ids": {
            "type": "_doc",
            "values": ["1001", "1005", "1011"]
        }
    }
}
multi_match/boost

multi_match:在多个字段中进行查询

POST /demeter_index/_doc/_search
{
    "query": {
        "multi_match": {
            "query": "小小明爱学习",
            "fields": ["desc", "nickname"]
        }
    }
}
在这里插入图片描述

boost:权重,为某个字段设置权重,权重越高,文档相关性得分越高。

#nickname^10代表nickname搜索提高了10倍相关性
POST /demeter_index/_doc/_search
{
    "query": {
        "multi_match": {
            "query": "小小明爱学习",
            "fields": ["desc", "nickname^10"]
        }
    }
}
在这里插入图片描述
布尔查询
  • must:返回的文档必须满足must子句的条件,并且参与计算分值

  • should:返回的文档可能满足should子句的条件。在一个Bool查询中,如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回。minimum_should_match参数定义了至少满足几个子句。

  • must_not:返回的文档必须不满足must_not定义的条件

POST /demeter_index/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "马可波罗",
            "fields": [
              "desc",
              "nickname"
            ]
          }
        },
        {
          "term": {
            "sex": 1
          }
        },
        {
          "term": {
            "age": 19
          }
        }
      ]
    }
  }
}
在这里插入图片描述

改成should

在这里插入图片描述

改成****must_not****


在这里插入图片描述

组合使用

POST /demeter_index/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "马",
            "fields": [
              "desc",
              "nickname"
            ]
          }
        }
      ],
      "should": [
        {
          "match": {
            "sex": 1
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "age": 18
          }
        }
      ]
    }
  }
}
在这里插入图片描述
过滤器

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

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

  • query:根据用户搜索条件检索匹配记录

  • post_filter:用于查询后,对结果数据的筛选

  1. gte:大于等于
  2. lte:小于等于
  3. gt:大于
  4. lt:小于
POST /demeter_index/_doc/_search
{
  "query": {
    "multi_match": {
      "query": "马",
      "fields": [
        "desc"
      ]
    }
  },
  "post_filter":{
    "range":{
      "money":{
        "gt":60,
        "lt":80
      }
    }
  }
}
在这里插入图片描述
排序

降序desc 升序asc

POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
            "desc": "马克"
        }
  },
  "post_filter":{
    "range":{
      "money":{
        "gt":60,
        "lt":80
      }
    }
  },
   "sort": [
        {
            "age": "desc"
        },
        {
            "money": "desc"
        }
    ]
}
在这里插入图片描述

对文本的排序

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

# 在创建mappings时 设置
"nickname": {
  "type": "text",
  "analyzer": "ik_max_word",
  "fields": {
    "keyword": {
      "type": "keyword"
    }
  }
}
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
            "desc": "马克"
        }
  },
  "post_filter":{
    "range":{
      "money":{
        "gt":60,
        "lt":80
      }
    }
  },
   "sort": [
        {
            "nickname.keyword": "desc"
        }
    ]
}
在这里插入图片描述
高亮 highlight
POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc": "马可"
    }
  },
  "highlight": {
    "fields": {
      "desc": {}
    }
  }
}
在这里插入图片描述

自定义高亮标签

POST /demeter_index/_doc/_search
{
  "query": {
    "match": {
      "desc": "马可"
    }
  },
  "highlight": {
    "pre_tags": [
      "<tag>"
    ],
    "post_tags": [
      "</tag>"
    ],
    "fields": {
      "desc": {}
    }
  }
}
在这里插入图片描述
prefix/fuzzy/wildcard

prefix:前缀查询,prefix 查询不做相关度评分计算,它只是将所有匹配的文档返回,并为每条结果赋予评分值 1 。它的行为更像是过滤器而不是查询。 prefix 查询和 prefix 过滤器这两者实际的区别就是过滤器是可以被缓存的,而查询不行。

POST /demeter_index/_doc/_search
{
  "query": {
    "prefix": {
      "desc": "elas"
    }
  }
}
在这里插入图片描述

fuzzy:模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。

POST /demeter_index/_doc/_search
{
  "query": {
    "fuzzy": {
      "desc": "elasticsearhc"
    }
  }
}
在这里插入图片描述

fuzziness,你的搜索文本最多可以纠正几个字母去跟你的数据进行匹配,默认如果不设置,就是2

POST /demeter_index/_doc/_search
{
  "query": {
    "multi_match": {
      "fields": [ "desc", "nickname"],
       "query": "elasticsearchs",
      "fuzziness": "auto"
    }
  }
}

wildcard:通配符查询

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