美文网首页
第二节:和elasticsearch的交互

第二节:和elasticsearch的交互

作者: 织雾呀 | 来源:发表于2019-07-30 15:52 被阅读0次

    Java API

    如果你正在使用 Java,在代码中你可以使用 Elasticsearch 内置的两个客户端:

    节点客户端(Node client)

    节点客户端作为一个非数据节点加入到本地集群中。换句话说,它本身不保存任何数据,但是它知道数据在集群中的哪个节点中,并且可以把请求转发到正确的节点。

    传输客户端(Transport client)

    轻量级的传输客户端可以将请求发送到远程集群。它本身不加入集群,但是它可以将请求转发到集群中的一个节点上。

    Java 客户端作为节点必须和 Elasticsearch 有相同的 主要 版本;否则,它们之间将无法互相理解。

    所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。

    一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

    curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
    

    < >标记的部件:

    名称 解释
    VERB 适当的 HTTP 方法 或 谓词 : GETPOSTPUTHEAD 或者 DELETE
    PROTOCOL http 或者 https(如果你在 Elasticsearch 前面有一个 https 代理)
    HOST Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
    PORT 运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
    PATH API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。
    QUERY_STRING 任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
    BODY 一个 JSON 格式的请求体 (如果请求需要的话)

    以上都是官方文档说的,我也不是很明白,但是我知道的是,可以通过http或者https交互
    所以上节安装了kibana,就直接用kibana交互!
    有些看客可能就要说了“你怎么能这么水呢!?自己都没看懂就贴出来”,根本没有!因为我也是第一次学嘛!


    按照官方文档的说法,xshell运行几个试试
    [root@cs3 /]# curl -XGET 'localhost:9200/_count?pretty' -d '
    > {
    >     "query": {
    >         "match_all": {}
    >     }
    > }'
    {
      "count" : 4,
      "_shards" : {
        "total" : 6,
        "successful" : 6,
        "skipped" : 0,
        "failed" : 0
      }
    }
    [root@cs3 /]# 
    
    

    kibana运行试试

    GET /_count
    {
        "query": {
            "match_all": {}
        }
    }
    

    输出:

    {
      "count": 4,
      "_shards": {
        "total": 6,
        "successful": 6,
        "skipped": 0,
        "failed": 0
      }
    }
    

    elasticsearch在这里引入了一个面向文档的概念

    面向文档

    在应用程序中对象很少只是一个简单的键和值的列表。通常,它们拥有更复杂的数据结构,可能包括日期、地理信息、其他对象或者数组等。
    也许有一天你想把这些对象存储在数据库中。使用关系型数据库的行和列存储,这相当于是把一个表现力丰富的对象塞到一个非常大的电子表格中:为了适应表结构,你必须设法将这个对象扁平化--通常一个字段对应一列--而且每次查询时又需要将其重新构造为对象。
    Elasticsearch 是 面向文档 的,意味着它存储整个对象或 文档_。Elasticsearch 不仅存储文档,而且 _索引 每个文档的内容,使之可以被检索。在 Elasticsearch 中,我们对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。

    Elasticsearch 使用 JavaScript Object Notation(或者 JSON)作为文档的序列化格式。

    下面这个 JSON 文档代表了一个 user 对象:

    {
        "email":      "john@smith.com",
        "first_name": "John",
        "last_name":  "Smith",
        "info": {
            "bio":         "Eco-warrior and defender of the weak",
            "age":         25,
            "interests": [ "dolphins", "whales" ]
        },
        "join_date": "2014/05/01"
    }
    

    实操

    创建一个雇员目录
    索引:存储数据到 Elasticsearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存储在哪里。

    一个 Elasticsearch 集群可以包含多个 索引 ,相应的每个索引可以包含多个 类型 。这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性

    索引 这个词在 Elasticsearch 语境中有多种含义, 这里有必要做一些说明:
    索引(名词)
    如前所述,一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方。 索引 (index) 的复数词为 indicesindexes
    索引(动词):
    索引一个文档 就是存储一个文档到一个 索引 (名词)中以便被检索和查询。这非常类似于 SQL 语句中的 INSERT 关键词,除了文档已存在时,新文档会替换旧文档情况之外。
    倒排索引
    关系型数据库通过增加一个 索引 比如一个 B树(B-tree)索引 到指定的列上,以便提升数据检索速度。Elasticsearch 和 Lucene 使用了一个叫做倒排索引 的结构来达到相同的目的。
    默认的,一个文档中的每一个属性都是 被索引 的(有一个倒排索引)和可搜索的。一个没有倒排索引的属性是不能被搜索到的。我们将在 倒排索引 讨论倒排索引的更多细节。

    插入:

    PUT /megacorp/employee/1
    {
        "first_name" : "John",
        "last_name" :  "Smith",
        "age" :        25,
        "about" :      "I love to go rock climbing",
        "interests": [ "sports", "music" ]
    }
    

    注意,路径 /megacorp/employee/1 包含了三部分的信息:

    - -
    megacorp 索引名称
    employee 类型名称
    1 特定雇员的ID

    请求体 —— JSON 文档 —— 包含了这位员工的所有详细信息,他的名字叫 John Smith ,今年 25 岁,喜欢攀岩。

    查询

    GET /megacorp/employee/1
    

    删除

    DELETE /megacorp/employee/1
    

    更新

    更新和插入一样,使用PUT

    PUT /megacorp/employee/1
    {
        "first_name" : "John",
        "last_name" :  "Smith",
        "age" :        25,
        "about" :      "我喜欢打游戏",
        "interests": [ "sports", "music" ]
    }
    

    使用 HEAD 指令来检查文档是否存在
    HEAD /megacorp/employee/1
    

    轻量级搜索

    搜索所有

    GET /megacorp/employee/_search
    

    当然直接搜索megacorp目录下的所有数据也是可以的

    GET /tang/_search
    
    image.png

    搜索姓氏为 Smith 的雇员

    GET /megacorp/employee/_search?q=last_name:Smith
    

    使用_search端点,并将查询本身赋值给参数 q=。返回结果给出了所有的 Smith:

    使用查询表达式搜索

    Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 它支持构建更加复杂和健壮的查询。

    领域特定语言 (DSL), 使用 JSON 构造了一个请求。我们可以像这样重写之前的查询所有名为 Smith 的搜索 :

    GET /megacorp/employee/_search
    {
        "query" : {
            "match" : {
                "last_name" : "Smith"
            }
        }
    }
    

    match:不再使用 query-string 参数,而是一个请求体替代。这个请求使用 JSON 构造,并使用了一个 match 查询

    更复杂的搜索

    使用过滤器,搜索姓氏为 Smith 的员工,且年龄大于 30

    GET /megacorp/employee/_search
    {
        "query" : {
            "bool": {
                "must": {
                    "match" : {
                        "last_name" : "smith" 
                    }
                },
                "filter": {
                    "range" : {
                        "age" : { "gt" : 30 } 
                    }
                }
            }
        }
    }
    

    全文搜索

    GET /megacorp/employee/_search
    {
        "query" : {
            "match" : {
                "about" : "rock climbing"
            }
        }
    }
    

    这里涉及到一个概念叫:相关性搜索

    Elasticsearch默认按照相关性得分排序,即每个文档跟查询的匹配程度。第一个最高得分的结果很明显:John Smith 的 about 属性清楚地写着 “rock climbing” 。
    但为什么 Jane Smith 也作为结果返回了呢?原因是她的 about 属性里提到了 “rock” 。因为只有 “rock” 而没有 “climbing” ,所以她的相关性得分低于 John 的。
    这是一个很好的案例,阐明了 Elasticsearch 如何 全文属性上搜索并返回相关性最强的结果。Elasticsearch中的 相关性 概念非常重要,也是完全区别于传统关系型数据库的一个概念,数据库中的一条记录要么匹配要么不匹配。

    短语搜索

    精确匹配一系列单词或者短语
    仅匹配同时包含 “rock” 和 “climbing” ,并且 二者以短语 “rock climbing” 的形式紧挨着的雇员记录。

    GET /megacorp/employee/_search
    {
        "query" : {
            "match_phrase" : {
                "about" : "rock climbing"
            }
        }
    }
    

    高亮搜索

    GET /megacorp/employee/_search
    {
        "query" : {
            "match_phrase" : {
                "about" : "打游戏"
            }
        },
        "highlight": {
            "fields" : {
                "about" : {}
            }
        }
    }
    

    当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:

    分析

    Elasticsearch 有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。

    GET /megacorp/employee/_search
    {
      "aggs": {
        "all_interests": {
          "terms": { "field": "interests" }
        }
      }
    }
    

    然后你就会发现报错了
    Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load
    这是因为5.x后对排序,聚合这些操作用单独的数据结构(fielddata)缓存到内存里了,需要单独开启,官方解释在此fielddata
    先执行这一步

    PUT megacorp/_mapping/employee/
    {
      "properties": {
        "interests": { 
          "type":     "text",
          "fielddata": true
        }
      }
    }
    

    如果想知道叫 Smith 的员工中最受欢迎的兴趣爱好,可以直接构造一个组合查询:

    GET /megacorp/employee/_search
    {
      "query": {
        "match": {
          "last_name": "smith"
        }
      },
      "aggs": {
        "all_interests": {
          "terms": {
            "field": "interests"
          }
        }
      }
    }
    

    这些语法也不用深究,之后会详细说明,这些用来体会elasticsearch的交互。

    相关文章

      网友评论

          本文标题:第二节:和elasticsearch的交互

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