zoukankan      html  css  js  c++  java
  • ES中的查询操作

    1、前缀查询

    先输入数据:

    PUT /my_index/address/1
    { "postcode": "W1 3DG" }
    
    PUT /my_index/address/2
    { "postcode": "W2F 8HW" }
    
    PUT /my_index/address/3
    { "postcode": "W1 7HW" }
    
    PUT /my_index/address/4
    { "postcode": "WC1N 1LZ" }
    
    PUT /my_index/address/5
    { "postcode": "SW5 0BE" }   

    为了找到所有以 W1 开始的邮编,可以使用简单的 prefix 查询:

    类似于SQL: select * from table where xx like 'xx%';

    GET /my_index/address/_search
    {
        "query": {
            "prefix": {
                "postcode": "W1"
            }
        }
    }

    2、短语匹配查询(match_phrase)

         在执行短语匹配查询时,ElasticSearch引擎首先分析(analyze)查询字符串,从分析后的文本中构建短语查询,这意味着必须匹配短语中的所有分词,并且保证各个分词的相对位置不变:

    POST /_search -d
    {  
       "from":1,
       "size":100,
       "fields":[ "eventname"],
       "query":{  
          "match_phrase":{  
             "eventname":"Open Source"
          }
       }
    }

    3、短语前缀匹配查询(match_phrase_prefix)

        除了把查询文本的最后一个分词只做前缀匹配之外,match_phrase_prefix和match_phrase查询基本一样,参数 max_expansions 控制最后一个单词会被重写成多少个前缀,也就是,控制前缀扩展成分词的数量,默认值是50。扩展的前缀数量越多,找到的文档数量就越多;如果前缀扩展的数量太少,可能查找不到相应的文档,遗漏数据。如代码所示,能够查到eventname包含"Open Source Hack Night"的文档。

    POST /_search -d
    {  
       "from":1,
       "size":100,
       "fields":[ "eventname" ],
       "query":{  
          "match_phrase_prefix":{  
             "eventname":{  
                "query":"Open Source hac",
                "max_expansions":50
             }
          }
       }
    }

    使用match性能往往是很高的,W1–> 扫描倒排索引 –> 一旦扫描到W1,就可以停了,因为带W1的就2个doc,已经找到了 –> 没有必要继续去搜索其他的term了;

     4、通配符与正则表达式查询

          与 prefix 前缀查询的特性类似, wildcard 通配符查询也是一种底层基于词的查询, 与前缀查询不同的是它允许指定匹配的正则式。它使用标准的 shell 通配符查询: ? 匹配任意字符, * 匹配 0 或多个字符。

      这个查询会匹配包含 W1F 7HW 和 W2F 8HW 的文档:

    GET /my_index/address/_search
    {
       "query": {
           "wildcard": {
               "postcode": "W?F*HW" 
           }
       }
    }

    ? 匹配 1 和 2 , * 与空格及 7 和 8 匹配。

    设想如果现在只想匹配 W 区域的所有邮编,前缀匹配也会包括以 WC 开头的所有邮编,与通配符匹配碰到的问题类似,如果想匹配只以 W 开始并跟随一个数字的所有邮编, regexp 正则式查询允许写出这样更复杂的模式:

    GET /my_index/address/_search
    {
       "query": {
           "regexp": {
               "postcode": "W[0-9].+" 
           }
       }
    }
    
    

     QueryBuilders.regexpQuery("postcode", "W[0-9].+");

        这个正则表达式要求词必须以 W 开头,紧跟 0 至 9 之间的任何一个数字,然后接一或多个其他字符。

         wildcard和regexp,与prefix原理一致,都会扫描整个索引,性能很差;数据在索引时的预处理有助于提高前缀匹配的效率,而通配符和正则表达式查询只能在查询时完成,尽管这些查询有其应用场景,但使用仍需谨慎。

    
    
  • 相关阅读:
    ThinkPHP5.1 行为与钩子
    PHP 商品秒杀抢购业务流程
    MySQL 读写分离
    Redis 管道
    Redis 事务
    Redis 锁机制
    ThinkPHP 实现队列
    MySQL 存储引擎
    分布式唯一ID分配问题
    Lightscape
  • 原文地址:https://www.cnblogs.com/JimShi/p/11520621.html
Copyright © 2011-2022 走看看