zoukankan      html  css  js  c++  java
  • ElasticSearch的查询(二)

    一、Query String search

      添加测试数据

    PUT test_search
    {
      "mappings": {
        "test_type": {
          "properties": {
            "dname": {
              "type": "text",
              "analyzer": "standard"
            },
            "ename": {
              "type": "text",
              "analyzer": "standard"
            },
            "eage": {
              "type": "long"
            },
            "hiredate": {
              "type": "date"
            },
            "gender": {
              "type": "keyword"
            }
          }
        }
      }
    }
    
    POST test_search/test_type/_bulk
    {"index":{}}
    {"dname":"Sales Department","ename":"张三","eage":20,"hiredate":"2019-01-01","gender":"男性"}
    {"index":{}}
    {"dname":"Sales Department","ename":"李四","eage":21,"hiredate":"2019-02-01","gender":"男性"}
    {"index":{}}
    {"dname":"Development Department","ename":"王五","eage":23,"hiredate":"2019-01-03","gender":"男性"}
    {"index":{}}
    {"dname":"Development Department","ename":"赵六","eage":26,"hiredate":"2018-01-01","gender":"男性"}
    {"index":{}}
    {"dname":"Development Department","ename":"韩梅梅","eage":24,"hiredate":"2019-03-01","gender":"女性"}
    {"index":{}}
    {"dname":"Development Department","ename":"钱虹","eage":29,"hiredate":"2018-03-01","gender":"女性"}
    View Code

      search的参数都是类似http请求头中的字符串参数提供搜索条件的

      GET [/index_name/type_name/]_search[?parameter_name=parameter_value&...]

    1,全搜索

      timeout参数:是超时时长定义。代表每个节点上的每个shard执行搜索时最多耗时多久。不会影响响应的正常返回。只会影响返回响应中的数据数量。

      如:索引a中,有10亿数据。存储在5个shard中,假设每个shard中2亿数据,执行全数据搜索的时候,需要耗时1000毫秒。定义timeout为10毫秒,代表的是shard执行10毫秒,搜索出多少数据,直接返回。

      在商业项目中,是禁止全数据搜索的。必须指定搜索的索引,类型和关键字。如果没有指定索引或类型,则代表开发目的不明确,需要重新做用例分析。如果没有关键字,称为索引内全搜索,也叫魔鬼搜索。

      GET [索引名/类型名/]_search?timeout=10ms

    结果返回:

    {
      "took": 144, #请求耗时多少毫秒
      "timed_out": false, #是否超时。默认情况下没有超时机制,也就是客户端等待ElasticSearch搜索结束(无论执行多久),提供超时机制的话,ElasticSearch则在指定时长内处理搜索,在指定时长结束的时候,将搜索的结果直接返回(无论是否搜索结束)。指定超时的方式是传递参数,参数单位是:毫秒-ms。秒-s。分钟-m。
      "_shards": {
        "total": 1, #请求发送到多少个shard上
        "successful": 1,#成功返回搜索结果的shard
        "skipped": 0, #停止服务的shard
        "failed": 0 #失败的shard
      },
      "hits": {
        "total": 1, #返回了多少结果
        "max_score": 1, #搜索结果中,最大的相关度分数,相关度越大分数越高,_score越大,排位越靠前。
        "hits": [ #搜索到的结果集合,默认查询前10条数据。
          {
            "_index": "test_index", #数据所在索引
            "_type": "my_type", #数据所在类型
            "_id": "1", #数据的id
            "_score": 1, #数据的搜索相关度分数
            "_source": { # 数据的具体内容。
              "field": "value"
            }
          }
        ]
      }
    }

    2,multi index搜索

      所谓的multi-index就是从多个index中搜索数据。相对使用较少,只有在复合数据搜索的时候,可能出现。一般来说,如果真使用复合数据搜索,都会使用_all。

      如:搜索引擎中的无条件搜索。(现在的应用中都被屏蔽了。使用的是默认搜索条件,执行数据搜索。 如: 电商中的搜索框默认值, 搜索引擎中的类别)

      无条件搜索,在搜索应用中称为“魔鬼搜索”,代表的是,搜索引擎会执行全数据检索,效率极低,且对资源有非常高的压力。

    GET _search #搜索所有的索引
    GET 索引名1,索引名2/_search # 搜索多个index中的数据
    GET 索引名/类型名/_search # 所属一个index中type的数据
    GET prefix_*/_search # 通配符搜索
    GET *_suffix/_search
    GET 索引名1,索引名2/类型名/_search # 搜索多个index中type的数据
    GET _all/_search  # _all代表所有的索引

    3,条件搜索

      query string search 搜索是通过HTTP请求的请求头传递参数的,默认的HTTP请求头字符集是ISO-8859-1,请求头传递中文会有乱码。

      GET 索引名/_search?q=字段名:搜索条件

    4,分页搜索

      默认情况下,ElasticSearch搜索返回结果是10条数据。从第0条开始查询

      GET 索引名/_search?from=0&size=10 # from 从第几行开始查询,行号从0开始。

    5,+/-搜索

    语法:

    GET 索引名/_search?q=字段名:条件   #不加+/-默认使用的是+
    GET 索引名/_search?q=+字段名:条件
    GET 索引名/_search?q=-字段名:条件

      + :和不定义符号含义一样,就是搜索指定的字段中包含keywords的数据,默认。

      - : 与+符号含义相反,就是搜索指定的字段中不包含keywords的数据。

    6,排序

      GET 索引名/_search?sort=字段名:排序规则

    案例:

    GET test_search/_search?sort=eage:asc
    GET test_search/_search?sort=eage:desc
    GET test_search/_search?sort=gender:desc,eage:desc

    二、DSL

      DSL - Domain Specified Language , 特殊领域的语言。

      请求参数是请求体传递的。在ElasticSearch中,请求体的字符集默认为UTF-8。

    语法:

    GET 索引名/_search
    {
       "command":{ "parameter_name" : "parameter_value"}
    }

    1,查询所有

    GET 索引名/_search
    {
       "query" : { "match_all" : {} }
    }

    2,match search

      全文检索。要求查询条件拆分后的任意词条具体数据匹配就算搜索结果。

    GET 索引名/_search
    {
      "query": {
        "match": {
          "字段名": "搜索条件"
        }
      }
    }

    3,phrase search

      短语检索。要求查询条件必须和具体数据完全匹配才算搜索结果。其特征是:1-搜索条件不做任何分词解析;2-在搜索字段对应的倒排索引(正排索引)中进行精确匹配,不再是简单的全文检索。

    GET 索引名/_search
    {
      "query": {
        "match_phrase": {
          "字段名": "搜索条件"
        }
      }
    }

    4,range

      范围检索

    GET 索引名/类型名/_search
    {
      "query" : {
        "range" : {
          "字段名" : {
            "gt" : 搜索条件1, 
            "lte" : 搜索条件2
          }
        }
      }
    }    

    5,term

      词组搜索。忽略搜索条件分词,在ElasticSearch倒排索引中进行精确匹配。

    GET 索引名/类型名/_search
    {
      "query" : {
        "term" : {
          "字段名": "搜索条件"
        }
      }
    }
    
    GET 索引名/类型名/_search
    {
      "query" : {
        "terms" : {
          "字段名": ["搜索条件1", "搜索条件2"]
        }
      }
    }
    • term是将传入的文本原封不动地(不分词)拿去查询
    • match会对输入进行分词处理后再去查询,部分命中的结果也会按照评分由高到低显示出来。
    • match_phrase是按短语查询,只有存在这个短语的文档才会被显示出来。会对传入的文本进行分词,但是必须完全匹配并且顺序相同

    6,多条件must、should、must_not

    • must数组中的多个条件必须同时满足
    • must_not数组中的多个条件必须都不满足
    • should数组中的多个条件有任意一个满足即可。
    GET 索引名/类型名/_search
    {
      "query": {
        "bool": {
          "must": [ #数组中的多个条件必须同时满足
            {
              "range": {
                "字段名": {
                  "lt": 条件
                }
              }
            }
          ],
          "must_not":[ #数组中的多个条件必须都不满足
            {
              "match": {
                "字段名": "条件"
              }
            },
            {
              "range": {
                "字段名": {
                  "gte": "搜索条件"
                }
              }
            }
          ],
          "should": [# 数组中的多个条件有任意一个满足即可。
            {
              "match": {
                "字段名": "条件"
              }
            },
            {
              "range": {
                "字段名": {
                  "gte": "搜索条件"
                }
              }
            }
          ]
        }
      }
    }

    7,排序

      在ElasticSearch的搜索中,默认是使用相关度分数实现排序的。可以通过搜索语法实现定制化排序。

    GET 索引名/类型名/_search
    {
      "query": {
        [搜索条件]
      },
      "sort": [
        {
          "字段名1": {
            "order": "asc"
          }
        },
        {
          "字段名2": {
            "order": "desc"
          }
        }
      ]
    }

      注意:在ElasticSearch中,如果使用text类型的字段作为排序依据,会有问题。ElasticSearch需要对text类型字段数据做分词处理。如果使用text类型字段做排序,ElasticSearch给出的排序结果未必友好,毕竟分词后,先使用哪一个单词做排序都是不合理的。所以ElasticSearch中默认情况下不允许使用text类型的字段做排序,如果需要使用字符串做结果排序,则可使用keyword类型字段作为排序依据,因为keyword字段不做分词处理。

    8,分页

      DSL分页也是使用from和size实现的。

    GET 索引名称/_search
    {
      "query":{
        "match_all":{}
    },
    "from": 起始下标,
    "size": 查询记录数
    }

    9,高亮

      在搜索中,经常需要对搜索关键字做高亮显示,这个时候就可以使用highlight语法。

    GET 索引名/_search
    {
      "query": {
        "match": {
          "字段名": "条件"
        }
      },
      "highlight": {
        "fields": {
          "要高亮显示的字段名": {
            "fragment_size": 5, #每个分段长度,默认20
            "number_of_fragments": 1 #返回多少个分段,默认3
          }
        },
        "pre_tags": ["前缀"], 
        "post_tags": ["后缀"] 
      }
    }

    案例:

    GET test_search/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "dname": "Development department"
              }
            },
            {
              "match": {
                "gender": "男性"
              }
            }
          ]
        }
      },
      "highlight": {
        "fields": {
          "dname": {
            "fragment_size": 20,
            "number_of_fragments": 1
          },
          "gender": {
            "fragment_size": 20,
            "number_of_fragments": 1
          }
        },
        "pre_tags": [
          "<span style='color:red'>"
        ],
        "post_tags": [
          "</span>"
        ]
      },
      "from": 2,
      "size": 2
    }

    10,聚合查询

    语法:

    "aggs": {
        "NAME": {# 指定结果的名称
          "AGG_TYPE": {# 指定具体的聚合方法,
            TODO: # 聚合体内制定具体的聚合字段
          }
        },
        "NAME": {# 指定结果的名称
          "AGG_TYPE": {# 指定具体的聚合方法,
            TODO: # 聚合体内制定具体的聚合字段
          }
        }
     }

      

    三、SpringDataElasticsearch

      源码:cloud-es

    1,添加pom文件

    <dependency>
        <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

    2,修改applicaiton配置

    #低版本使用5.x,注意使用的springdata的版本与es是否对应
    spring.data.elasticsearch.cluster-name=es5-cluster
    spring.data.elasticsearch.cluster-nodes= hadoop208:9300,hadoop209:9300
    #高版本使用6.x
    spring.elasticsearch.rest.uris=http://hadoop208:9200,http://hadoop209:9200

    3,创建实体

      案例:Item对象

    • @Document指定实体类和索引对应关系@Id 指定主键
      • indexName:索引名称
      • type: 索引类型(不加会给默认,es7之后删除)
      • shards: 主分片数量,默认5
      • replicas:复制分片数量,默认1
    • @Field指定普通属性
      • type: 对应Elasticsearch中属性类型。使用FiledType枚举可以快速获取。测试发现没有type属性可能出现无法自动创建类型问题,所以一定要有type属性。
      • text类型能被分词
      • keywords不能被分词
      • index: 是否创建索引。作为搜索条件时index必须为true
      • analyzer:指定分词器类型。
      • fielddata:指定是否为text类型字段创建正向索引。默认为false,设置为true则可以使用此字段排序

    4,使用方式

      案例:ItemTest

  • 相关阅读:
    cas 重复登录问题解决了。但是两个页签都是已登录状态,一个页签退出,另外一个页签正常访问应用程序。会出现下面报错信息。待解决
    flask 结合cas 出现的问题
    实验场景:两个页面登录状态下,一个logout.然后重新登录,一个页面刷新
    flask 生成excel并下载
    为什么不能在shell脚本中执行source /etc/profile或者source ~/.bashrc问题?
    centos7实现ssh免秘钥分发
    Drbd+Heatbeat实现NFS共享文件存储高可用
    docker监控方案实践(cadvisor+influxdb+grafana)
    centos7.5部署ELk
    keepalived+haproxy实现高可用负载均衡
  • 原文地址:https://www.cnblogs.com/bbgs-xc/p/14350093.html
Copyright © 2011-2022 走看看