美文网首页
ElasticSearch系列文章四 DSL搜索

ElasticSearch系列文章四 DSL搜索

作者: 哭泣哭泣帕拉达 | 来源:发表于2020-07-16 17:01 被阅读0次

    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": "马?"
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:ElasticSearch系列文章四 DSL搜索

          本文链接:https://www.haomeiwen.com/subject/pbfmhktx.html