美文网首页elasticsearch玩转大数据elasticsearch
二十二、Elasticsearch前缀匹配、通配符搜索和正则搜索

二十二、Elasticsearch前缀匹配、通配符搜索和正则搜索

作者: 编程界的小学生 | 来源:发表于2017-07-17 14:16 被阅读1969次

    1、本章所讲内容好比SQL中的模糊查询

    2、数据准备

    PUT /my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "title" : {
              "type": "keyword"
            }
          }
        }
      }
    }
    

    准备三条数据

    POST /my_index/my_type/1
    {
      "title" : "C3D0-KD345"
    }
    
    POST /my_index/my_type/2
    {
      "title" : "C3K5-DFG65"
    }
    
    POST /my_index/my_type/3
    {
      "title" : "C4I8-UI365"
    }
    

    3、前缀匹配

    类似于SQL中的右模糊。 like 'xxx%'

    需求:上面已经插入了三条数据:

    C3D0-KD345
    C3K5-DFG65
    C4I8-UI365
    

    搜出以C3开头的document

    GET /my_index/my_type/_search
    {
      "query": {
        "prefix": {
          "title": {
            "value": "C3"
          }
        }
      }
    }
    

    结果:

    {
      "took": 56,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 2,
        "max_score": 1,
        "hits": [
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "2",
            "_score": 1,
            "_source": {
              "title": "C3K5-DFG65"
            }
          },
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "1",
            "_score": 1,
            "_source": {
              "title": "C3D0-KD345"
            }
          }
        ]
      }
    }
    

    4、前缀匹配的原理

    从上面结果可以看出两条数据的score都是1,从而可知,prefix query不计算relevance score,与filter唯一的区别是filter会cache bitset

    前缀越短,要处理的doc越多,性能越差,尽可能用长前缀搜索

    问:为什么性能不好?原理是怎样的?
    答:
    假设有三个doc

    doc1:C3-D0-KD345
    doc2:C3-K5-DFG65
    doc3:C4-I8-UI365
    

    通过

    GET /_analyze
    {
      "text": "C3-D0-KD345",
      "analyzer": "standard"
    }
    

    分析出他的分词结果如下:

    c3          doc1,doc2都有此term
    d0
    kd345
    k5
    dfg65
    c4
    i8
    ui365
    

    match性能是很高的,为什么?
    C3 --》扫描倒排索引 --》一旦扫描到C3就可以停了。已经找到了,没必要继续搜索其他term了。比如这里第一个就是C3,那搜索的时候扫描完第一个term就停了,因为已经找到了。

    prefix性能很低,为什么?

    因为前缀搜索不分词,还是如下的term

    C3-D0-KD345
    C3-K5-DFG65
    C4-I8-UI365
    

    c3 --> 先扫描到了C3-D0-KD345,很棒,找到了一个前缀带c3的字符串 --> 还是要继续搜索的,因为后面还有一个C3-K5-DFG65,也许还有其他很多的前缀带c3的字符串 --> 你扫描到了一个前缀匹配的term,不能停,必须继续搜索 --> 直到扫描完整个的倒排索引,才能结束

    所以prefix相对于match来讲性能很差。

    5、通配符搜索

    可完成SQL中的左模糊+右模糊+全模糊
    跟前缀搜索类似,但是功能更加强大,但是性能依旧差,原理同prefix。

    C3D0-KD345
    C3K5-DFG65
    C4I8-UI365
    

    (1)搜索以C3开头的

    GET /my_index/my_type/_search
    {
      "query": {
        "wildcard": {
          "title": {
            "value": "C3?*"
          }
        }
      }
    }
    

    (2)搜索以C开头的第二个字符随意,第三个字符必须是K的,最后一个字符必须是5的doc

    GET /my_index/my_type/_search
    {
      "query": {
        "wildcard": {
          "title": {
            "value": "C?K*5"
          }
        }
      }
    }
    

    (3)搜索包含数字6的doc

    GET /my_index/my_type/_search
    {
      "query": {
        "wildcard": {
          "title": {
            "value": "*6*"
          }
        }
      }
    }
    

    ?:任意字符
    *:0个或任意多个字符

    6、正则搜索

    可完成SQL中的左模糊+右模糊+全模糊
    跟前缀搜索类似,但是功能更加强大,但是性能依旧差,原理同prefix。

    查看以C开头,第二个是随便1个数字,末尾是345的doc

    GET /my_index/my_type/_search
    {
      "query": {
        "regexp" : {
          "title" : "C[0-9].+345"
        }
      }
    }
    

    [0-9]:指定范围内的数字
    [a-z]:指定范围内的字母
    .:一个字符
    +:前面的正则表达式可以出现一次或多次

    若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
    欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:


    qrcode_for_gh_577b64e73701_258.jpg

    相关文章

      网友评论

        本文标题:二十二、Elasticsearch前缀匹配、通配符搜索和正则搜索

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